authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-15 18:06:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-15 18:06:29-07:00
logd6467dcf71c40d4f09993f8c449b33adeca55ce5
treecba752c3cba158e29f40e813693ebcbe8e4a8259
parent21606339af2712d94bb3cfdcc9050287c5a2134c

update clang tools to 13 rc1


4 files changed, 105 insertions(+), 352 deletions(-)

src/zig_clang_cc1_main.cpp+9-6
......@@ -203,6 +203,12 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
203203 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
204204 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
205205 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
206
207 // Setup round-trip remarks for the DiagnosticsEngine used in CreateFromArgs.
208 if (find(Argv, StringRef("-Rround-trip-cc1-args")) != Argv.end())
209 Diags.setSeverity(diag::remark_cc1_round_trip_generated,
210 diag::Severity::Remark, {});
211
206212 bool Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(),
207213 Argv, Diags, Argv0);
208214
......@@ -248,12 +254,9 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
248254 if (llvm::timeTraceProfilerEnabled()) {
249255 SmallString<128> Path(Clang->getFrontendOpts().OutputFile);
250256 llvm::sys::path::replace_extension(Path, "json");
251 if (auto profilerOutput =
252 Clang->createOutputFile(Path.str(),
253 /*Binary=*/false,
254 /*RemoveFileOnSignal=*/false,
255 /*useTemporary=*/false)) {
256
257 if (auto profilerOutput = Clang->createOutputFile(
258 Path.str(), /*Binary=*/false, /*RemoveFileOnSignal=*/false,
259 /*useTemporary=*/false)) {
257260 llvm::timeTraceProfilerWrite(*profilerOutput);
258261 // FIXME(ibiryukov): make profilerOutput flush in destructor instead.
259262 profilerOutput->flush();
src/zig_clang_cc1as_main.cpp+34-27
......@@ -91,6 +91,7 @@ struct AssemblerInvocation {
9191 unsigned SaveTemporaryLabels : 1;
9292 unsigned GenDwarfForAssembly : 1;
9393 unsigned RelaxELFRelocations : 1;
94 unsigned Dwarf64 : 1;
9495 unsigned DwarfVersion;
9596 std::string DwarfDebugFlags;
9697 std::string DwarfDebugProducer;
......@@ -160,6 +161,7 @@ public:
160161 FatalWarnings = 0;
161162 NoWarn = 0;
162163 IncrementalLinkerCompatible = 0;
164 Dwarf64 = 0;
163165 DwarfVersion = 0;
164166 EmbedBitcode = 0;
165167 }
......@@ -231,13 +233,16 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
231233 }
232234
233235 Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations);
236 if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32))
237 Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64);
234238 Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags);
235239 Opts.DwarfDebugFlags =
236240 std::string(Args.getLastArgValue(OPT_dwarf_debug_flags));
237241 Opts.DwarfDebugProducer =
238242 std::string(Args.getLastArgValue(OPT_dwarf_debug_producer));
239 Opts.DebugCompilationDir =
240 std::string(Args.getLastArgValue(OPT_fdebug_compilation_dir));
243 if (const Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ,
244 options::OPT_fdebug_compilation_dir_EQ))
245 Opts.DebugCompilationDir = A->getValue();
241246 Opts.MainFileName = std::string(Args.getLastArgValue(OPT_main_file_name));
242247
243248 for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) {
......@@ -319,7 +324,7 @@ getOutputStream(StringRef Path, DiagnosticsEngine &Diags, bool Binary) {
319324
320325 std::error_code EC;
321326 auto Out = std::make_unique<raw_fd_ostream>(
322 Path, EC, (Binary ? sys::fs::OF_None : sys::fs::OF_Text));
327 Path, EC, (Binary ? sys::fs::OF_None : sys::fs::OF_TextWithCRLF));
323328 if (EC) {
324329 Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message();
325330 return nullptr;
......@@ -328,8 +333,8 @@ getOutputStream(StringRef Path, DiagnosticsEngine &Diags, bool Binary) {
328333 return Out;
329334}
330335
331static bool ExecuteAssembler(AssemblerInvocation &Opts,
332 DiagnosticsEngine &Diags) {
336static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
337 DiagnosticsEngine &Diags) {
333338 // Get the target specific parser.
334339 std::string Error;
335340 const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
......@@ -337,7 +342,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
337342 return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
338343
339344 ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
340 MemoryBuffer::getFileOrSTDIN(Opts.InputFile);
345 MemoryBuffer::getFileOrSTDIN(Opts.InputFile, /*IsText=*/true);
341346
342347 if (std::error_code EC = Buffer.getError()) {
343348 Error = EC.message();
......@@ -378,11 +383,15 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
378383 if (!Opts.SplitDwarfOutput.empty())
379384 DwoOS = getOutputStream(Opts.SplitDwarfOutput, Diags, IsBinary);
380385
381 // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
382 // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
383 std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
386 // Build up the feature string from the target feature list.
387 std::string FS = llvm::join(Opts.Features, ",");
384388
385 MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr, &MCOptions);
389 std::unique_ptr<MCSubtargetInfo> STI(
390 TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
391 assert(STI && "Unable to create subtarget info!");
392
393 MCContext Ctx(Triple(Opts.Triple), MAI.get(), MRI.get(), STI.get(), &SrcMgr,
394 &MCOptions);
386395
387396 bool PIC = false;
388397 if (Opts.RelocationModel == "static") {
......@@ -395,7 +404,12 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
395404 PIC = false;
396405 }
397406
398 MOFI->InitMCObjectFileInfo(Triple(Opts.Triple), PIC, Ctx);
407 // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
408 // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
409 std::unique_ptr<MCObjectFileInfo> MOFI(
410 TheTarget->createMCObjectFileInfo(Ctx, PIC));
411 Ctx.setObjectFileInfo(MOFI.get());
412
399413 if (Opts.SaveTemporaryLabels)
400414 Ctx.setAllowTemporaryLabels(false);
401415 if (Opts.GenDwarfForAssembly)
......@@ -417,23 +431,17 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
417431 Ctx.addDebugPrefixMapEntry(KV.first, KV.second);
418432 if (!Opts.MainFileName.empty())
419433 Ctx.setMainFileName(StringRef(Opts.MainFileName));
434 Ctx.setDwarfFormat(Opts.Dwarf64 ? dwarf::DWARF64 : dwarf::DWARF32);
420435 Ctx.setDwarfVersion(Opts.DwarfVersion);
421436 if (Opts.GenDwarfForAssembly)
422437 Ctx.setGenDwarfRootFile(Opts.InputFile,
423438 SrcMgr.getMemoryBuffer(BufferIndex)->getBuffer());
424439
425 // Build up the feature string from the target feature list.
426 std::string FS = llvm::join(Opts.Features, ",");
427
428440 std::unique_ptr<MCStreamer> Str;
429441
430442 std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
431443 assert(MCII && "Unable to create instruction info!");
432444
433 std::unique_ptr<MCSubtargetInfo> STI(
434 TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
435 assert(STI && "Unable to create subtarget info!");
436
437445 raw_pwrite_stream *Out = FDOS.get();
438446 std::unique_ptr<buffer_ostream> BOS;
439447
......@@ -487,8 +495,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
487495
488496 // When -fembed-bitcode is passed to clang_as, a 1-byte marker
489497 // is emitted in __LLVM,__asm section if the object file is MachO format.
490 if (Opts.EmbedBitcode && Ctx.getObjectFileInfo()->getObjectFileType() ==
491 MCObjectFileInfo::IsMachO) {
498 if (Opts.EmbedBitcode && Ctx.getObjectFileType() == MCContext::IsMachO) {
492499 MCSection *AsmLabel = Ctx.getMachOSection(
493500 "__LLVM", "__asm", MachO::S_REGULAR, 4, SectionKind::getReadOnly());
494501 Str.get()->SwitchSection(AsmLabel);
......@@ -525,12 +532,12 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
525532 Failed = Parser->Run(Opts.NoInitialTextSection);
526533 }
527534
528 // Parser has a reference to the output stream (Str), so close Parser first.
529 Parser.reset();
530 Str.reset();
531 // Close the output stream early.
532 BOS.reset();
533 FDOS.reset();
535 return Failed;
536}
537
538static bool ExecuteAssembler(AssemblerInvocation &Opts,
539 DiagnosticsEngine &Diags) {
540 bool Failed = ExecuteAssemblerImpl(Opts, Diags);
534541
535542 // Delete output file if there were errors.
536543 if (Failed) {
......@@ -578,7 +585,7 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
578585 return 1;
579586
580587 if (Asm.ShowHelp) {
581 getDriverOptTable().PrintHelp(
588 getDriverOptTable().printHelp(
582589 llvm::outs(), "clang -cc1as [options] file...",
583590 "Clang Integrated Assembler",
584591 /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0,
src/zig_clang_driver.cpp+54-52
......@@ -242,20 +242,28 @@ static void getCLEnvVarOptions(std::string &EnvValue, llvm::StringSaver &Saver,
242242}
243243
244244static void SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
245 // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
246 TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
247 if (TheDriver.CCPrintOptions)
248 TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE");
249
250 // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE.
251 TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS");
252 if (TheDriver.CCPrintHeaders)
253 TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE");
254
255 // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE.
256 TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS");
257 if (TheDriver.CCLogDiagnostics)
258 TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
245 auto CheckEnvVar = [](const char *EnvOptSet, const char *EnvOptFile,
246 std::string &OptFile) {
247 bool OptSet = !!::getenv(EnvOptSet);
248 if (OptSet) {
249 if (const char *Var = ::getenv(EnvOptFile))
250 OptFile = Var;
251 }
252 return OptSet;
253 };
254
255 TheDriver.CCPrintOptions =
256 CheckEnvVar("CC_PRINT_OPTIONS", "CC_PRINT_OPTIONS_FILE",
257 TheDriver.CCPrintOptionsFilename);
258 TheDriver.CCPrintHeaders =
259 CheckEnvVar("CC_PRINT_HEADERS", "CC_PRINT_HEADERS_FILE",
260 TheDriver.CCPrintHeadersFilename);
261 TheDriver.CCLogDiagnostics =
262 CheckEnvVar("CC_LOG_DIAGNOSTICS", "CC_LOG_DIAGNOSTICS_FILE",
263 TheDriver.CCLogDiagnosticsFilename);
264 TheDriver.CCPrintProcessStats =
265 CheckEnvVar("CC_PRINT_PROC_STAT", "CC_PRINT_PROC_STAT_FILE",
266 TheDriver.CCPrintStatReportFilename);
259267}
260268
261269static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient,
......@@ -263,7 +271,7 @@ static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient,
263271 // If the clang binary happens to be named cl.exe for compatibility reasons,
264272 // use clang-cl.exe as the prefix to avoid confusion between clang and MSVC.
265273 StringRef ExeBasename(llvm::sys::path::stem(Path));
266 if (ExeBasename.equals_lower("cl"))
274 if (ExeBasename.equals_insensitive("cl"))
267275 ExeBasename = "clang-cl";
268276 DiagClient->setPrefix(std::string(ExeBasename));
269277}
......@@ -335,56 +343,49 @@ static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV) {
335343 return 1;
336344}
337345
338extern "C" int ZigClang_main(int argc_, const char **argv_);
339int ZigClang_main(int argc_, const char **argv_) {
346extern "C" int ZigClang_main(int Argc, const char **Argv);
347int ZigClang_main(int Argc, const char **Argv) {
340348 noteBottomOfStack();
341
342 // ZIG MOD: On windows, InitLLVM calls GetCommandLineW(),
349 // ZIG PATCH: On Windows, InitLLVM calls GetCommandLineW(),
343350 // and overwrites the args. We don't want it to do that,
344351 // and we also don't need the signal handlers it installs
345352 // (we have our own already), so we just use llvm_shutdown_obj
346353 // instead.
347 // llvm::InitLLVM X(argc_, argv_);
354 // llvm::InitLLVM X(Argc, Argv);
348355 llvm::llvm_shutdown_obj X;
349356
350357 llvm::setBugReportMsg("PLEASE submit a bug report to " BUG_REPORT_URL
351358 " and include the crash backtrace, preprocessed "
352359 "source, and associated run script.\n");
353 size_t argv_offset = (strcmp(argv_[1], "-cc1") == 0 || strcmp(argv_[1], "-cc1as") == 0) ? 0 : 1;
354 SmallVector<const char *, 256> argv(argv_ + argv_offset, argv_ + argc_);
360 size_t argv_offset = (strcmp(Argv[1], "-cc1") == 0 || strcmp(Argv[1], "-cc1as") == 0) ? 0 : 1;
361 SmallVector<const char *, 256> Args(Argv + argv_offset, Argv + Argc);
355362
356363 if (llvm::sys::Process::FixupStandardFileDescriptors())
357364 return 1;
358365
359366 llvm::InitializeAllTargets();
360 auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(argv[0]);
361367
362368 llvm::BumpPtrAllocator A;
363369 llvm::StringSaver Saver(A);
364370
365371 // Parse response files using the GNU syntax, unless we're in CL mode. There
366 // are two ways to put clang in CL compatibility mode: argv[0] is either
372 // are two ways to put clang in CL compatibility mode: Args[0] is either
367373 // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
368374 // command line parsing can't happen until after response file parsing, so we
369375 // have to manually search for a --driver-mode=cl argument the hard way.
370376 // Finally, our -cc1 tools don't care which tokenization mode we use because
371377 // response files written by clang will tokenize the same way in either mode.
372 bool ClangCLMode = false;
373 if (StringRef(TargetAndMode.DriverMode).equals("--driver-mode=cl") ||
374 llvm::find_if(argv, [](const char *F) {
375 return F && strcmp(F, "--driver-mode=cl") == 0;
376 }) != argv.end()) {
377 ClangCLMode = true;
378 }
378 bool ClangCLMode =
379 IsClangCL(getDriverMode(Args[0], llvm::makeArrayRef(Args).slice(1)));
379380 enum { Default, POSIX, Windows } RSPQuoting = Default;
380 for (const char *F : argv) {
381 for (const char *F : Args) {
381382 if (strcmp(F, "--rsp-quoting=posix") == 0)
382383 RSPQuoting = POSIX;
383384 else if (strcmp(F, "--rsp-quoting=windows") == 0)
384385 RSPQuoting = Windows;
385386 }
386387
387 // Determines whether we want nullptr markers in argv to indicate response
388 // Determines whether we want nullptr markers in Args to indicate response
388389 // files end-of-lines. We only use this for the /LINK driver argument with
389390 // clang-cl.exe on Windows.
390391 bool MarkEOLs = ClangCLMode;
......@@ -395,31 +396,31 @@ int ZigClang_main(int argc_, const char **argv_) {
395396 else
396397 Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
397398
398 if (MarkEOLs && argv.size() > 1 && StringRef(argv[1]).startswith("-cc1"))
399 if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).startswith("-cc1"))
399400 MarkEOLs = false;
400 llvm::cl::ExpandResponseFiles(Saver, Tokenizer, argv, MarkEOLs);
401 llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Args, MarkEOLs);
401402
402403 // Handle -cc1 integrated tools, even if -cc1 was expanded from a response
403404 // file.
404 auto FirstArg = std::find_if(argv.begin() + 1, argv.end(),
405 auto FirstArg = std::find_if(Args.begin() + 1, Args.end(),
405406 [](const char *A) { return A != nullptr; });
406 if (FirstArg != argv.end() && StringRef(*FirstArg).startswith("-cc1")) {
407 if (FirstArg != Args.end() && StringRef(*FirstArg).startswith("-cc1")) {
407408 // If -cc1 came from a response file, remove the EOL sentinels.
408409 if (MarkEOLs) {
409 auto newEnd = std::remove(argv.begin(), argv.end(), nullptr);
410 argv.resize(newEnd - argv.begin());
410 auto newEnd = std::remove(Args.begin(), Args.end(), nullptr);
411 Args.resize(newEnd - Args.begin());
411412 }
412 return ExecuteCC1Tool(argv);
413 return ExecuteCC1Tool(Args);
413414 }
414415
415416 // Handle options that need handling before the real command line parsing in
416417 // Driver::BuildCompilation()
417418 bool CanonicalPrefixes = true;
418 for (int i = 1, size = argv.size(); i < size; ++i) {
419 for (int i = 1, size = Args.size(); i < size; ++i) {
419420 // Skip end-of-line response file markers
420 if (argv[i] == nullptr)
421 if (Args[i] == nullptr)
421422 continue;
422 if (StringRef(argv[i]) == "-no-canonical-prefixes") {
423 if (StringRef(Args[i]) == "-no-canonical-prefixes") {
423424 CanonicalPrefixes = false;
424425 break;
425426 }
......@@ -435,7 +436,7 @@ int ZigClang_main(int argc_, const char **argv_) {
435436 getCLEnvVarOptions(OptCL.getValue(), Saver, PrependedOpts);
436437
437438 // Insert right after the program name to prepend to the argument list.
438 argv.insert(argv.begin() + 1, PrependedOpts.begin(), PrependedOpts.end());
439 Args.insert(Args.begin() + 1, PrependedOpts.begin(), PrependedOpts.end());
439440 }
440441 // Arguments in "_CL_" are appended.
441442 llvm::Optional<std::string> Opt_CL_ = llvm::sys::Process::GetEnv("_CL_");
......@@ -444,7 +445,7 @@ int ZigClang_main(int argc_, const char **argv_) {
444445 getCLEnvVarOptions(Opt_CL_.getValue(), Saver, AppendedOpts);
445446
446447 // Insert at the end of the argument list to append.
447 argv.append(AppendedOpts.begin(), AppendedOpts.end());
448 Args.append(AppendedOpts.begin(), AppendedOpts.end());
448449 }
449450 }
450451
......@@ -453,12 +454,12 @@ int ZigClang_main(int argc_, const char **argv_) {
453454 // scenes.
454455 if (const char *OverrideStr = ::getenv("CCC_OVERRIDE_OPTIONS")) {
455456 // FIXME: Driver shouldn't take extra initial argument.
456 ApplyQAOverride(argv, OverrideStr, SavedStrings);
457 ApplyQAOverride(Args, OverrideStr, SavedStrings);
457458 }
458459
459 // Pass local param `argv_[0]` as fallback.
460 // Pass local param `Argv[0]` as fallback.
460461 // See https://github.com/ziglang/zig/pull/3292 .
461 std::string Path = GetExecutablePath(argv_[0], CanonicalPrefixes);
462 std::string Path = GetExecutablePath(Argv[0], CanonicalPrefixes);
462463
463464 // Whether the cc1 tool should be called inside the current process, or if we
464465 // should spawn a new clang subprocess (old behavior).
......@@ -467,7 +468,7 @@ int ZigClang_main(int argc_, const char **argv_) {
467468 bool UseNewCC1Process;
468469
469470 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
470 CreateAndPopulateDiagOpts(argv, UseNewCC1Process);
471 CreateAndPopulateDiagOpts(Args, UseNewCC1Process);
471472
472473 TextDiagnosticPrinter *DiagClient
473474 = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
......@@ -488,10 +489,11 @@ int ZigClang_main(int argc_, const char **argv_) {
488489 ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
489490
490491 Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
491 SetInstallDir(argv, TheDriver, CanonicalPrefixes);
492 SetInstallDir(Args, TheDriver, CanonicalPrefixes);
493 auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(Args[0]);
492494 TheDriver.setTargetAndMode(TargetAndMode);
493495
494 insertTargetAndModeArgs(TargetAndMode, argv, SavedStrings);
496 insertTargetAndModeArgs(TargetAndMode, Args, SavedStrings);
495497
496498 SetBackdoorDriverOutputsFromEnvVars(TheDriver);
497499
......@@ -501,7 +503,7 @@ int ZigClang_main(int argc_, const char **argv_) {
501503 llvm::CrashRecoveryContext::Enable();
502504 }
503505
504 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
506 std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Args));
505507 int Res = 1;
506508 bool IsCrash = false;
507509 if (C && !C->containsError()) {
src/zig_llvm-ar.cpp+8-267
......@@ -1,263 +1,3 @@
1// In this file is copy+pasted WindowsSupport.h from LLVM 12.0.1-rc1.
2// This is so that we can patch it. The upstream sources are incorrectly
3// including "llvm/Config/config.h" which is a private header and thus not
4// available in the include files distributed with LLVM.
5// The patch here changes it to include "llvm/Config/config.h" instead.
6// Patch submitted upstream: https://reviews.llvm.org/D103370
7#if !defined(_WIN32)
8#define LLVM_SUPPORT_WINDOWSSUPPORT_H
9#endif
10
11//===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===//
12//
13// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
14// See https://llvm.org/LICENSE.txt for license information.
15// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
16//
17//===----------------------------------------------------------------------===//
18//
19// This file defines things specific to Windows implementations. In addition to
20// providing some helpers for working with win32 APIs, this header wraps
21// <windows.h> with some portability macros. Always include WindowsSupport.h
22// instead of including <windows.h> directly.
23//
24//===----------------------------------------------------------------------===//
25
26//===----------------------------------------------------------------------===//
27//=== WARNING: Implementation here must contain only generic Win32 code that
28//=== is guaranteed to work on *all* Win32 variants.
29//===----------------------------------------------------------------------===//
30
31#ifndef LLVM_SUPPORT_WINDOWSSUPPORT_H
32#define LLVM_SUPPORT_WINDOWSSUPPORT_H
33
34// mingw-w64 tends to define it as 0x0502 in its headers.
35#undef _WIN32_WINNT
36#undef _WIN32_IE
37
38// Require at least Windows 7 API.
39#define _WIN32_WINNT 0x0601
40#define _WIN32_IE 0x0800 // MinGW at it again. FIXME: verify if still needed.
41#define WIN32_LEAN_AND_MEAN
42#ifndef NOMINMAX
43#define NOMINMAX
44#endif
45
46#include "llvm/ADT/SmallVector.h"
47#include "llvm/ADT/StringExtras.h"
48#include "llvm/ADT/StringRef.h"
49#include "llvm/ADT/Twine.h"
50#include "llvm/Config/llvm-config.h" // Get build system configuration settings
51#include "llvm/Support/Allocator.h"
52#include "llvm/Support/Chrono.h"
53#include "llvm/Support/Compiler.h"
54#include "llvm/Support/ErrorHandling.h"
55#include "llvm/Support/VersionTuple.h"
56#include <cassert>
57#include <string>
58#include <system_error>
59#include <windows.h>
60
61// Must be included after windows.h
62#include <wincrypt.h>
63
64namespace llvm {
65
66/// Determines if the program is running on Windows 8 or newer. This
67/// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
68/// to supercede raw calls to GetVersionEx. Old SDKs, Cygwin, and MinGW don't
69/// yet have VersionHelpers.h, so we have our own helper.
70bool RunningWindows8OrGreater();
71
72/// Returns the Windows version as Major.Minor.0.BuildNumber. Uses
73/// RtlGetVersion or GetVersionEx under the hood depending on what is available.
74/// GetVersionEx is deprecated, but this API exposes the build number which can
75/// be useful for working around certain kernel bugs.
76llvm::VersionTuple GetWindowsOSVersion();
77
78bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix);
79
80// Include GetLastError() in a fatal error message.
81LLVM_ATTRIBUTE_NORETURN inline void ReportLastErrorFatal(const char *Msg) {
82 std::string ErrMsg;
83 MakeErrMsg(&ErrMsg, Msg);
84 llvm::report_fatal_error(ErrMsg);
85}
86
87template <typename HandleTraits>
88class ScopedHandle {
89 typedef typename HandleTraits::handle_type handle_type;
90 handle_type Handle;
91
92 ScopedHandle(const ScopedHandle &other) = delete;
93 void operator=(const ScopedHandle &other) = delete;
94public:
95 ScopedHandle()
96 : Handle(HandleTraits::GetInvalid()) {}
97
98 explicit ScopedHandle(handle_type h)
99 : Handle(h) {}
100
101 ~ScopedHandle() {
102 if (HandleTraits::IsValid(Handle))
103 HandleTraits::Close(Handle);
104 }
105
106 handle_type take() {
107 handle_type t = Handle;
108 Handle = HandleTraits::GetInvalid();
109 return t;
110 }
111
112 ScopedHandle &operator=(handle_type h) {
113 if (HandleTraits::IsValid(Handle))
114 HandleTraits::Close(Handle);
115 Handle = h;
116 return *this;
117 }
118
119 // True if Handle is valid.
120 explicit operator bool() const {
121 return HandleTraits::IsValid(Handle) ? true : false;
122 }
123
124 operator handle_type() const {
125 return Handle;
126 }
127};
128
129struct CommonHandleTraits {
130 typedef HANDLE handle_type;
131
132 static handle_type GetInvalid() {
133 return INVALID_HANDLE_VALUE;
134 }
135
136 static void Close(handle_type h) {
137 ::CloseHandle(h);
138 }
139
140 static bool IsValid(handle_type h) {
141 return h != GetInvalid();
142 }
143};
144
145struct JobHandleTraits : CommonHandleTraits {
146 static handle_type GetInvalid() {
147 return NULL;
148 }
149};
150
151struct CryptContextTraits : CommonHandleTraits {
152 typedef HCRYPTPROV handle_type;
153
154 static handle_type GetInvalid() {
155 return 0;
156 }
157
158 static void Close(handle_type h) {
159 ::CryptReleaseContext(h, 0);
160 }
161
162 static bool IsValid(handle_type h) {
163 return h != GetInvalid();
164 }
165};
166
167struct RegTraits : CommonHandleTraits {
168 typedef HKEY handle_type;
169
170 static handle_type GetInvalid() {
171 return NULL;
172 }
173
174 static void Close(handle_type h) {
175 ::RegCloseKey(h);
176 }
177
178 static bool IsValid(handle_type h) {
179 return h != GetInvalid();
180 }
181};
182
183struct FindHandleTraits : CommonHandleTraits {
184 static void Close(handle_type h) {
185 ::FindClose(h);
186 }
187};
188
189struct FileHandleTraits : CommonHandleTraits {};
190
191typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle;
192typedef ScopedHandle<FileHandleTraits> ScopedFileHandle;
193typedef ScopedHandle<CryptContextTraits> ScopedCryptContext;
194typedef ScopedHandle<RegTraits> ScopedRegHandle;
195typedef ScopedHandle<FindHandleTraits> ScopedFindHandle;
196typedef ScopedHandle<JobHandleTraits> ScopedJobHandle;
197
198template <class T>
199class SmallVectorImpl;
200
201template <class T>
202typename SmallVectorImpl<T>::const_pointer
203c_str(SmallVectorImpl<T> &str) {
204 str.push_back(0);
205 str.pop_back();
206 return str.data();
207}
208
209namespace sys {
210
211inline std::chrono::nanoseconds toDuration(FILETIME Time) {
212 ULARGE_INTEGER TimeInteger;
213 TimeInteger.LowPart = Time.dwLowDateTime;
214 TimeInteger.HighPart = Time.dwHighDateTime;
215
216 // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
217 return std::chrono::nanoseconds(100 * TimeInteger.QuadPart);
218}
219
220inline TimePoint<> toTimePoint(FILETIME Time) {
221 ULARGE_INTEGER TimeInteger;
222 TimeInteger.LowPart = Time.dwLowDateTime;
223 TimeInteger.HighPart = Time.dwHighDateTime;
224
225 // Adjust for different epoch
226 TimeInteger.QuadPart -= 11644473600ll * 10000000;
227
228 // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
229 return TimePoint<>(std::chrono::nanoseconds(100 * TimeInteger.QuadPart));
230}
231
232inline FILETIME toFILETIME(TimePoint<> TP) {
233 ULARGE_INTEGER TimeInteger;
234 TimeInteger.QuadPart = TP.time_since_epoch().count() / 100;
235 TimeInteger.QuadPart += 11644473600ll * 10000000;
236
237 FILETIME Time;
238 Time.dwLowDateTime = TimeInteger.LowPart;
239 Time.dwHighDateTime = TimeInteger.HighPart;
240 return Time;
241}
242
243namespace windows {
244// Returns command line arguments. Unlike arguments given to main(),
245// this function guarantees that the returned arguments are encoded in
246// UTF-8 regardless of the current code page setting.
247std::error_code GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
248 BumpPtrAllocator &Alloc);
249
250/// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode
251/// File API.
252std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
253 size_t MaxPathLen = MAX_PATH);
254
255} // end namespace windows
256} // end namespace sys
257} // end namespace llvm.
258
259#endif
260
2611//===-- llvm-ar.cpp - LLVM archive librarian utility ----------------------===//
2622//
2633// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
......@@ -386,9 +126,9 @@ MODIFIERS:
386126)";
387127
388128static void printHelpMessage() {
389 if (Stem.contains_lower("ranlib"))
129 if (Stem.contains_insensitive("ranlib"))
390130 outs() << RanlibHelp;
391 else if (Stem.contains_lower("ar"))
131 else if (Stem.contains_insensitive("ar"))
392132 outs() << ArHelp;
393133}
394134
......@@ -530,7 +270,8 @@ static void getArchive() {
530270}
531271
532272static object::Archive &readLibrary(const Twine &Library) {
533 auto BufOrErr = MemoryBuffer::getFile(Library, -1, false);
273 auto BufOrErr = MemoryBuffer::getFile(Library, /*IsText=*/false,
274 /*RequiresNullTerminator=*/false);
534275 failIfError(BufOrErr.getError(), "could not open library " + Library);
535276 ArchiveBuffers.push_back(std::move(*BufOrErr));
536277 auto LibOrErr =
......@@ -1255,8 +996,8 @@ static void performOperation(ArchiveOperation Operation,
1255996static int performOperation(ArchiveOperation Operation,
1256997 std::vector<NewArchiveMember> *NewMembers) {
1257998 // Create or open the archive object.
1258 ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
1259 MemoryBuffer::getFile(ArchiveName, -1, false);
999 ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFile(
1000 ArchiveName, /*IsText=*/false, /*RequiresNullTerminator=*/false);
12601001 std::error_code EC = Buf.getError();
12611002 if (EC && EC != errc::no_such_file_or_directory)
12621003 fail("unable to open '" + ArchiveName + "': " + EC.message());
......@@ -1522,7 +1263,7 @@ static int ranlib_main(int argc, char **argv) {
15221263
15231264extern "C" int ZigLlvmAr_main(int argc, char **argv);
15241265int ZigLlvmAr_main(int argc, char **argv) {
1525 // ZIG MOD: On windows, InitLLVM calls GetCommandLineW(),
1266 // ZIG PATCH: On Windows, InitLLVM calls GetCommandLineW(),
15261267 // and overwrites the args. We don't want it to do that,
15271268 // and we also don't need the signal handlers it installs
15281269 // (we have our own already), so we just use llvm_shutdown_obj
......@@ -1543,7 +1284,7 @@ int ZigLlvmAr_main(int argc, char **argv) {
15431284 // Lib.exe -> lib (see D44808, MSBuild runs Lib.exe)
15441285 // dlltool.exe -> dlltool
15451286 // arm-pokymllib32-linux-gnueabi-llvm-ar-10 -> ar
1546 auto I = Stem.rfind_lower(Tool);
1287 auto I = Stem.rfind_insensitive(Tool);
15471288 return I != StringRef::npos &&
15481289 (I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()]));
15491290 };