diff --git a/src/zig_clang_cc1_main.cpp b/src/zig_clang_cc1_main.cpp index 0918860015..396d6ff529 100644 --- a/src/zig_clang_cc1_main.cpp +++ b/src/zig_clang_cc1_main.cpp @@ -203,6 +203,12 @@ int cc1_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); + + // Setup round-trip remarks for the DiagnosticsEngine used in CreateFromArgs. + if (find(Argv, StringRef("-Rround-trip-cc1-args")) != Argv.end()) + Diags.setSeverity(diag::remark_cc1_round_trip_generated, + diag::Severity::Remark, {}); + bool Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(), Argv, Diags, Argv0); @@ -248,12 +254,9 @@ int cc1_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { if (llvm::timeTraceProfilerEnabled()) { SmallString<128> Path(Clang->getFrontendOpts().OutputFile); llvm::sys::path::replace_extension(Path, "json"); - if (auto profilerOutput = - Clang->createOutputFile(Path.str(), - /*Binary=*/false, - /*RemoveFileOnSignal=*/false, - /*useTemporary=*/false)) { - + if (auto profilerOutput = Clang->createOutputFile( + Path.str(), /*Binary=*/false, /*RemoveFileOnSignal=*/false, + /*useTemporary=*/false)) { llvm::timeTraceProfilerWrite(*profilerOutput); // FIXME(ibiryukov): make profilerOutput flush in destructor instead. profilerOutput->flush(); diff --git a/src/zig_clang_cc1as_main.cpp b/src/zig_clang_cc1as_main.cpp index de71026fbf..086ce0ea77 100644 --- a/src/zig_clang_cc1as_main.cpp +++ b/src/zig_clang_cc1as_main.cpp @@ -91,6 +91,7 @@ struct AssemblerInvocation { unsigned SaveTemporaryLabels : 1; unsigned GenDwarfForAssembly : 1; unsigned RelaxELFRelocations : 1; + unsigned Dwarf64 : 1; unsigned DwarfVersion; std::string DwarfDebugFlags; std::string DwarfDebugProducer; @@ -160,6 +161,7 @@ public: FatalWarnings = 0; NoWarn = 0; IncrementalLinkerCompatible = 0; + Dwarf64 = 0; DwarfVersion = 0; EmbedBitcode = 0; } @@ -231,13 +233,16 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, } Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations); + if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32)) + Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64); Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags); Opts.DwarfDebugFlags = std::string(Args.getLastArgValue(OPT_dwarf_debug_flags)); Opts.DwarfDebugProducer = std::string(Args.getLastArgValue(OPT_dwarf_debug_producer)); - Opts.DebugCompilationDir = - std::string(Args.getLastArgValue(OPT_fdebug_compilation_dir)); + if (const Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ, + options::OPT_fdebug_compilation_dir_EQ)) + Opts.DebugCompilationDir = A->getValue(); Opts.MainFileName = std::string(Args.getLastArgValue(OPT_main_file_name)); for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) { @@ -319,7 +324,7 @@ getOutputStream(StringRef Path, DiagnosticsEngine &Diags, bool Binary) { std::error_code EC; auto Out = std::make_unique( - Path, EC, (Binary ? sys::fs::OF_None : sys::fs::OF_Text)); + Path, EC, (Binary ? sys::fs::OF_None : sys::fs::OF_TextWithCRLF)); if (EC) { Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message(); return nullptr; @@ -328,8 +333,8 @@ getOutputStream(StringRef Path, DiagnosticsEngine &Diags, bool Binary) { return Out; } -static bool ExecuteAssembler(AssemblerInvocation &Opts, - DiagnosticsEngine &Diags) { +static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, + DiagnosticsEngine &Diags) { // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error); @@ -337,7 +342,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; ErrorOr> Buffer = - MemoryBuffer::getFileOrSTDIN(Opts.InputFile); + MemoryBuffer::getFileOrSTDIN(Opts.InputFile, /*IsText=*/true); if (std::error_code EC = Buffer.getError()) { Error = EC.message(); @@ -378,11 +383,15 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, if (!Opts.SplitDwarfOutput.empty()) DwoOS = getOutputStream(Opts.SplitDwarfOutput, Diags, IsBinary); - // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and - // MCObjectFileInfo needs a MCContext reference in order to initialize itself. - std::unique_ptr MOFI(new MCObjectFileInfo()); + // Build up the feature string from the target feature list. + std::string FS = llvm::join(Opts.Features, ","); - MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr, &MCOptions); + std::unique_ptr STI( + TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS)); + assert(STI && "Unable to create subtarget info!"); + + MCContext Ctx(Triple(Opts.Triple), MAI.get(), MRI.get(), STI.get(), &SrcMgr, + &MCOptions); bool PIC = false; if (Opts.RelocationModel == "static") { @@ -395,7 +404,12 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, PIC = false; } - MOFI->InitMCObjectFileInfo(Triple(Opts.Triple), PIC, Ctx); + // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and + // MCObjectFileInfo needs a MCContext reference in order to initialize itself. + std::unique_ptr MOFI( + TheTarget->createMCObjectFileInfo(Ctx, PIC)); + Ctx.setObjectFileInfo(MOFI.get()); + if (Opts.SaveTemporaryLabels) Ctx.setAllowTemporaryLabels(false); if (Opts.GenDwarfForAssembly) @@ -417,23 +431,17 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Ctx.addDebugPrefixMapEntry(KV.first, KV.second); if (!Opts.MainFileName.empty()) Ctx.setMainFileName(StringRef(Opts.MainFileName)); + Ctx.setDwarfFormat(Opts.Dwarf64 ? dwarf::DWARF64 : dwarf::DWARF32); Ctx.setDwarfVersion(Opts.DwarfVersion); if (Opts.GenDwarfForAssembly) Ctx.setGenDwarfRootFile(Opts.InputFile, SrcMgr.getMemoryBuffer(BufferIndex)->getBuffer()); - // Build up the feature string from the target feature list. - std::string FS = llvm::join(Opts.Features, ","); - std::unique_ptr Str; std::unique_ptr MCII(TheTarget->createMCInstrInfo()); assert(MCII && "Unable to create instruction info!"); - std::unique_ptr STI( - TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS)); - assert(STI && "Unable to create subtarget info!"); - raw_pwrite_stream *Out = FDOS.get(); std::unique_ptr BOS; @@ -487,8 +495,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, // When -fembed-bitcode is passed to clang_as, a 1-byte marker // is emitted in __LLVM,__asm section if the object file is MachO format. - if (Opts.EmbedBitcode && Ctx.getObjectFileInfo()->getObjectFileType() == - MCObjectFileInfo::IsMachO) { + if (Opts.EmbedBitcode && Ctx.getObjectFileType() == MCContext::IsMachO) { MCSection *AsmLabel = Ctx.getMachOSection( "__LLVM", "__asm", MachO::S_REGULAR, 4, SectionKind::getReadOnly()); Str.get()->SwitchSection(AsmLabel); @@ -525,12 +532,12 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Failed = Parser->Run(Opts.NoInitialTextSection); } - // Parser has a reference to the output stream (Str), so close Parser first. - Parser.reset(); - Str.reset(); - // Close the output stream early. - BOS.reset(); - FDOS.reset(); + return Failed; +} + +static bool ExecuteAssembler(AssemblerInvocation &Opts, + DiagnosticsEngine &Diags) { + bool Failed = ExecuteAssemblerImpl(Opts, Diags); // Delete output file if there were errors. if (Failed) { @@ -578,7 +585,7 @@ int cc1as_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { return 1; if (Asm.ShowHelp) { - getDriverOptTable().PrintHelp( + getDriverOptTable().printHelp( llvm::outs(), "clang -cc1as [options] file...", "Clang Integrated Assembler", /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0, diff --git a/src/zig_clang_driver.cpp b/src/zig_clang_driver.cpp index e358fea83a..3c38250df3 100644 --- a/src/zig_clang_driver.cpp +++ b/src/zig_clang_driver.cpp @@ -242,20 +242,28 @@ static void getCLEnvVarOptions(std::string &EnvValue, llvm::StringSaver &Saver, } static void SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) { - // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE. - TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS"); - if (TheDriver.CCPrintOptions) - TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE"); + auto CheckEnvVar = [](const char *EnvOptSet, const char *EnvOptFile, + std::string &OptFile) { + bool OptSet = !!::getenv(EnvOptSet); + if (OptSet) { + if (const char *Var = ::getenv(EnvOptFile)) + OptFile = Var; + } + return OptSet; + }; - // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE. - TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS"); - if (TheDriver.CCPrintHeaders) - TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE"); - - // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE. - TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS"); - if (TheDriver.CCLogDiagnostics) - TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE"); + TheDriver.CCPrintOptions = + CheckEnvVar("CC_PRINT_OPTIONS", "CC_PRINT_OPTIONS_FILE", + TheDriver.CCPrintOptionsFilename); + TheDriver.CCPrintHeaders = + CheckEnvVar("CC_PRINT_HEADERS", "CC_PRINT_HEADERS_FILE", + TheDriver.CCPrintHeadersFilename); + TheDriver.CCLogDiagnostics = + CheckEnvVar("CC_LOG_DIAGNOSTICS", "CC_LOG_DIAGNOSTICS_FILE", + TheDriver.CCLogDiagnosticsFilename); + TheDriver.CCPrintProcessStats = + CheckEnvVar("CC_PRINT_PROC_STAT", "CC_PRINT_PROC_STAT_FILE", + TheDriver.CCPrintStatReportFilename); } static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient, @@ -263,7 +271,7 @@ static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient, // If the clang binary happens to be named cl.exe for compatibility reasons, // use clang-cl.exe as the prefix to avoid confusion between clang and MSVC. StringRef ExeBasename(llvm::sys::path::stem(Path)); - if (ExeBasename.equals_lower("cl")) + if (ExeBasename.equals_insensitive("cl")) ExeBasename = "clang-cl"; DiagClient->setPrefix(std::string(ExeBasename)); } @@ -335,56 +343,49 @@ static int ExecuteCC1Tool(SmallVectorImpl &ArgV) { return 1; } -extern "C" int ZigClang_main(int argc_, const char **argv_); -int ZigClang_main(int argc_, const char **argv_) { +extern "C" int ZigClang_main(int Argc, const char **Argv); +int ZigClang_main(int Argc, const char **Argv) { noteBottomOfStack(); - - // ZIG MOD: On windows, InitLLVM calls GetCommandLineW(), + // ZIG PATCH: On Windows, InitLLVM calls GetCommandLineW(), // and overwrites the args. We don't want it to do that, // and we also don't need the signal handlers it installs // (we have our own already), so we just use llvm_shutdown_obj // instead. - // llvm::InitLLVM X(argc_, argv_); + // llvm::InitLLVM X(Argc, Argv); llvm::llvm_shutdown_obj X; llvm::setBugReportMsg("PLEASE submit a bug report to " BUG_REPORT_URL " and include the crash backtrace, preprocessed " "source, and associated run script.\n"); - size_t argv_offset = (strcmp(argv_[1], "-cc1") == 0 || strcmp(argv_[1], "-cc1as") == 0) ? 0 : 1; - SmallVector argv(argv_ + argv_offset, argv_ + argc_); + size_t argv_offset = (strcmp(Argv[1], "-cc1") == 0 || strcmp(Argv[1], "-cc1as") == 0) ? 0 : 1; + SmallVector Args(Argv + argv_offset, Argv + Argc); if (llvm::sys::Process::FixupStandardFileDescriptors()) return 1; llvm::InitializeAllTargets(); - auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(argv[0]); llvm::BumpPtrAllocator A; llvm::StringSaver Saver(A); // Parse response files using the GNU syntax, unless we're in CL mode. There - // are two ways to put clang in CL compatibility mode: argv[0] is either + // are two ways to put clang in CL compatibility mode: Args[0] is either // clang-cl or cl, or --driver-mode=cl is on the command line. The normal // command line parsing can't happen until after response file parsing, so we // have to manually search for a --driver-mode=cl argument the hard way. // Finally, our -cc1 tools don't care which tokenization mode we use because // response files written by clang will tokenize the same way in either mode. - bool ClangCLMode = false; - if (StringRef(TargetAndMode.DriverMode).equals("--driver-mode=cl") || - llvm::find_if(argv, [](const char *F) { - return F && strcmp(F, "--driver-mode=cl") == 0; - }) != argv.end()) { - ClangCLMode = true; - } + bool ClangCLMode = + IsClangCL(getDriverMode(Args[0], llvm::makeArrayRef(Args).slice(1))); enum { Default, POSIX, Windows } RSPQuoting = Default; - for (const char *F : argv) { + for (const char *F : Args) { if (strcmp(F, "--rsp-quoting=posix") == 0) RSPQuoting = POSIX; else if (strcmp(F, "--rsp-quoting=windows") == 0) RSPQuoting = Windows; } - // Determines whether we want nullptr markers in argv to indicate response + // Determines whether we want nullptr markers in Args to indicate response // files end-of-lines. We only use this for the /LINK driver argument with // clang-cl.exe on Windows. bool MarkEOLs = ClangCLMode; @@ -395,31 +396,31 @@ int ZigClang_main(int argc_, const char **argv_) { else Tokenizer = &llvm::cl::TokenizeGNUCommandLine; - if (MarkEOLs && argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) + if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).startswith("-cc1")) MarkEOLs = false; - llvm::cl::ExpandResponseFiles(Saver, Tokenizer, argv, MarkEOLs); + llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Args, MarkEOLs); // Handle -cc1 integrated tools, even if -cc1 was expanded from a response // file. - auto FirstArg = std::find_if(argv.begin() + 1, argv.end(), + auto FirstArg = std::find_if(Args.begin() + 1, Args.end(), [](const char *A) { return A != nullptr; }); - if (FirstArg != argv.end() && StringRef(*FirstArg).startswith("-cc1")) { + if (FirstArg != Args.end() && StringRef(*FirstArg).startswith("-cc1")) { // If -cc1 came from a response file, remove the EOL sentinels. if (MarkEOLs) { - auto newEnd = std::remove(argv.begin(), argv.end(), nullptr); - argv.resize(newEnd - argv.begin()); + auto newEnd = std::remove(Args.begin(), Args.end(), nullptr); + Args.resize(newEnd - Args.begin()); } - return ExecuteCC1Tool(argv); + return ExecuteCC1Tool(Args); } // Handle options that need handling before the real command line parsing in // Driver::BuildCompilation() bool CanonicalPrefixes = true; - for (int i = 1, size = argv.size(); i < size; ++i) { + for (int i = 1, size = Args.size(); i < size; ++i) { // Skip end-of-line response file markers - if (argv[i] == nullptr) + if (Args[i] == nullptr) continue; - if (StringRef(argv[i]) == "-no-canonical-prefixes") { + if (StringRef(Args[i]) == "-no-canonical-prefixes") { CanonicalPrefixes = false; break; } @@ -435,7 +436,7 @@ int ZigClang_main(int argc_, const char **argv_) { getCLEnvVarOptions(OptCL.getValue(), Saver, PrependedOpts); // Insert right after the program name to prepend to the argument list. - argv.insert(argv.begin() + 1, PrependedOpts.begin(), PrependedOpts.end()); + Args.insert(Args.begin() + 1, PrependedOpts.begin(), PrependedOpts.end()); } // Arguments in "_CL_" are appended. llvm::Optional Opt_CL_ = llvm::sys::Process::GetEnv("_CL_"); @@ -444,7 +445,7 @@ int ZigClang_main(int argc_, const char **argv_) { getCLEnvVarOptions(Opt_CL_.getValue(), Saver, AppendedOpts); // Insert at the end of the argument list to append. - argv.append(AppendedOpts.begin(), AppendedOpts.end()); + Args.append(AppendedOpts.begin(), AppendedOpts.end()); } } @@ -453,12 +454,12 @@ int ZigClang_main(int argc_, const char **argv_) { // scenes. if (const char *OverrideStr = ::getenv("CCC_OVERRIDE_OPTIONS")) { // FIXME: Driver shouldn't take extra initial argument. - ApplyQAOverride(argv, OverrideStr, SavedStrings); + ApplyQAOverride(Args, OverrideStr, SavedStrings); } - // Pass local param `argv_[0]` as fallback. + // Pass local param `Argv[0]` as fallback. // See https://github.com/ziglang/zig/pull/3292 . - std::string Path = GetExecutablePath(argv_[0], CanonicalPrefixes); + std::string Path = GetExecutablePath(Argv[0], CanonicalPrefixes); // Whether the cc1 tool should be called inside the current process, or if we // should spawn a new clang subprocess (old behavior). @@ -467,7 +468,7 @@ int ZigClang_main(int argc_, const char **argv_) { bool UseNewCC1Process; IntrusiveRefCntPtr DiagOpts = - CreateAndPopulateDiagOpts(argv, UseNewCC1Process); + CreateAndPopulateDiagOpts(Args, UseNewCC1Process); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); @@ -488,10 +489,11 @@ int ZigClang_main(int argc_, const char **argv_) { ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false); Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags); - SetInstallDir(argv, TheDriver, CanonicalPrefixes); + SetInstallDir(Args, TheDriver, CanonicalPrefixes); + auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(Args[0]); TheDriver.setTargetAndMode(TargetAndMode); - insertTargetAndModeArgs(TargetAndMode, argv, SavedStrings); + insertTargetAndModeArgs(TargetAndMode, Args, SavedStrings); SetBackdoorDriverOutputsFromEnvVars(TheDriver); @@ -501,7 +503,7 @@ int ZigClang_main(int argc_, const char **argv_) { llvm::CrashRecoveryContext::Enable(); } - std::unique_ptr C(TheDriver.BuildCompilation(argv)); + std::unique_ptr C(TheDriver.BuildCompilation(Args)); int Res = 1; bool IsCrash = false; if (C && !C->containsError()) { diff --git a/src/zig_llvm-ar.cpp b/src/zig_llvm-ar.cpp index e4c376adbc..b48cd811d9 100644 --- a/src/zig_llvm-ar.cpp +++ b/src/zig_llvm-ar.cpp @@ -1,263 +1,3 @@ -// In this file is copy+pasted WindowsSupport.h from LLVM 12.0.1-rc1. -// This is so that we can patch it. The upstream sources are incorrectly -// including "llvm/Config/config.h" which is a private header and thus not -// available in the include files distributed with LLVM. -// The patch here changes it to include "llvm/Config/config.h" instead. -// Patch submitted upstream: https://reviews.llvm.org/D103370 -#if !defined(_WIN32) -#define LLVM_SUPPORT_WINDOWSSUPPORT_H -#endif - -//===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines things specific to Windows implementations. In addition to -// providing some helpers for working with win32 APIs, this header wraps -// with some portability macros. Always include WindowsSupport.h -// instead of including directly. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic Win32 code that -//=== is guaranteed to work on *all* Win32 variants. -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_WINDOWSSUPPORT_H -#define LLVM_SUPPORT_WINDOWSSUPPORT_H - -// mingw-w64 tends to define it as 0x0502 in its headers. -#undef _WIN32_WINNT -#undef _WIN32_IE - -// Require at least Windows 7 API. -#define _WIN32_WINNT 0x0601 -#define _WIN32_IE 0x0800 // MinGW at it again. FIXME: verify if still needed. -#define WIN32_LEAN_AND_MEAN -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Config/llvm-config.h" // Get build system configuration settings -#include "llvm/Support/Allocator.h" -#include "llvm/Support/Chrono.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/VersionTuple.h" -#include -#include -#include -#include - -// Must be included after windows.h -#include - -namespace llvm { - -/// Determines if the program is running on Windows 8 or newer. This -/// reimplements one of the helpers in the Windows 8.1 SDK, which are intended -/// to supercede raw calls to GetVersionEx. Old SDKs, Cygwin, and MinGW don't -/// yet have VersionHelpers.h, so we have our own helper. -bool RunningWindows8OrGreater(); - -/// Returns the Windows version as Major.Minor.0.BuildNumber. Uses -/// RtlGetVersion or GetVersionEx under the hood depending on what is available. -/// GetVersionEx is deprecated, but this API exposes the build number which can -/// be useful for working around certain kernel bugs. -llvm::VersionTuple GetWindowsOSVersion(); - -bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix); - -// Include GetLastError() in a fatal error message. -LLVM_ATTRIBUTE_NORETURN inline void ReportLastErrorFatal(const char *Msg) { - std::string ErrMsg; - MakeErrMsg(&ErrMsg, Msg); - llvm::report_fatal_error(ErrMsg); -} - -template -class ScopedHandle { - typedef typename HandleTraits::handle_type handle_type; - handle_type Handle; - - ScopedHandle(const ScopedHandle &other) = delete; - void operator=(const ScopedHandle &other) = delete; -public: - ScopedHandle() - : Handle(HandleTraits::GetInvalid()) {} - - explicit ScopedHandle(handle_type h) - : Handle(h) {} - - ~ScopedHandle() { - if (HandleTraits::IsValid(Handle)) - HandleTraits::Close(Handle); - } - - handle_type take() { - handle_type t = Handle; - Handle = HandleTraits::GetInvalid(); - return t; - } - - ScopedHandle &operator=(handle_type h) { - if (HandleTraits::IsValid(Handle)) - HandleTraits::Close(Handle); - Handle = h; - return *this; - } - - // True if Handle is valid. - explicit operator bool() const { - return HandleTraits::IsValid(Handle) ? true : false; - } - - operator handle_type() const { - return Handle; - } -}; - -struct CommonHandleTraits { - typedef HANDLE handle_type; - - static handle_type GetInvalid() { - return INVALID_HANDLE_VALUE; - } - - static void Close(handle_type h) { - ::CloseHandle(h); - } - - static bool IsValid(handle_type h) { - return h != GetInvalid(); - } -}; - -struct JobHandleTraits : CommonHandleTraits { - static handle_type GetInvalid() { - return NULL; - } -}; - -struct CryptContextTraits : CommonHandleTraits { - typedef HCRYPTPROV handle_type; - - static handle_type GetInvalid() { - return 0; - } - - static void Close(handle_type h) { - ::CryptReleaseContext(h, 0); - } - - static bool IsValid(handle_type h) { - return h != GetInvalid(); - } -}; - -struct RegTraits : CommonHandleTraits { - typedef HKEY handle_type; - - static handle_type GetInvalid() { - return NULL; - } - - static void Close(handle_type h) { - ::RegCloseKey(h); - } - - static bool IsValid(handle_type h) { - return h != GetInvalid(); - } -}; - -struct FindHandleTraits : CommonHandleTraits { - static void Close(handle_type h) { - ::FindClose(h); - } -}; - -struct FileHandleTraits : CommonHandleTraits {}; - -typedef ScopedHandle ScopedCommonHandle; -typedef ScopedHandle ScopedFileHandle; -typedef ScopedHandle ScopedCryptContext; -typedef ScopedHandle ScopedRegHandle; -typedef ScopedHandle ScopedFindHandle; -typedef ScopedHandle ScopedJobHandle; - -template -class SmallVectorImpl; - -template -typename SmallVectorImpl::const_pointer -c_str(SmallVectorImpl &str) { - str.push_back(0); - str.pop_back(); - return str.data(); -} - -namespace sys { - -inline std::chrono::nanoseconds toDuration(FILETIME Time) { - ULARGE_INTEGER TimeInteger; - TimeInteger.LowPart = Time.dwLowDateTime; - TimeInteger.HighPart = Time.dwHighDateTime; - - // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond) - return std::chrono::nanoseconds(100 * TimeInteger.QuadPart); -} - -inline TimePoint<> toTimePoint(FILETIME Time) { - ULARGE_INTEGER TimeInteger; - TimeInteger.LowPart = Time.dwLowDateTime; - TimeInteger.HighPart = Time.dwHighDateTime; - - // Adjust for different epoch - TimeInteger.QuadPart -= 11644473600ll * 10000000; - - // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond) - return TimePoint<>(std::chrono::nanoseconds(100 * TimeInteger.QuadPart)); -} - -inline FILETIME toFILETIME(TimePoint<> TP) { - ULARGE_INTEGER TimeInteger; - TimeInteger.QuadPart = TP.time_since_epoch().count() / 100; - TimeInteger.QuadPart += 11644473600ll * 10000000; - - FILETIME Time; - Time.dwLowDateTime = TimeInteger.LowPart; - Time.dwHighDateTime = TimeInteger.HighPart; - return Time; -} - -namespace windows { -// Returns command line arguments. Unlike arguments given to main(), -// this function guarantees that the returned arguments are encoded in -// UTF-8 regardless of the current code page setting. -std::error_code GetCommandLineArguments(SmallVectorImpl &Args, - BumpPtrAllocator &Alloc); - -/// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode -/// File API. -std::error_code widenPath(const Twine &Path8, SmallVectorImpl &Path16, - size_t MaxPathLen = MAX_PATH); - -} // end namespace windows -} // end namespace sys -} // end namespace llvm. - -#endif - //===-- llvm-ar.cpp - LLVM archive librarian utility ----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -386,9 +126,9 @@ MODIFIERS: )"; static void printHelpMessage() { - if (Stem.contains_lower("ranlib")) + if (Stem.contains_insensitive("ranlib")) outs() << RanlibHelp; - else if (Stem.contains_lower("ar")) + else if (Stem.contains_insensitive("ar")) outs() << ArHelp; } @@ -530,7 +270,8 @@ static void getArchive() { } static object::Archive &readLibrary(const Twine &Library) { - auto BufOrErr = MemoryBuffer::getFile(Library, -1, false); + auto BufOrErr = MemoryBuffer::getFile(Library, /*IsText=*/false, + /*RequiresNullTerminator=*/false); failIfError(BufOrErr.getError(), "could not open library " + Library); ArchiveBuffers.push_back(std::move(*BufOrErr)); auto LibOrErr = @@ -1255,8 +996,8 @@ static void performOperation(ArchiveOperation Operation, static int performOperation(ArchiveOperation Operation, std::vector *NewMembers) { // Create or open the archive object. - ErrorOr> Buf = - MemoryBuffer::getFile(ArchiveName, -1, false); + ErrorOr> Buf = MemoryBuffer::getFile( + ArchiveName, /*IsText=*/false, /*RequiresNullTerminator=*/false); std::error_code EC = Buf.getError(); if (EC && EC != errc::no_such_file_or_directory) fail("unable to open '" + ArchiveName + "': " + EC.message()); @@ -1522,7 +1263,7 @@ static int ranlib_main(int argc, char **argv) { extern "C" int ZigLlvmAr_main(int argc, char **argv); int ZigLlvmAr_main(int argc, char **argv) { - // ZIG MOD: On windows, InitLLVM calls GetCommandLineW(), + // ZIG PATCH: On Windows, InitLLVM calls GetCommandLineW(), // and overwrites the args. We don't want it to do that, // and we also don't need the signal handlers it installs // (we have our own already), so we just use llvm_shutdown_obj @@ -1543,7 +1284,7 @@ int ZigLlvmAr_main(int argc, char **argv) { // Lib.exe -> lib (see D44808, MSBuild runs Lib.exe) // dlltool.exe -> dlltool // arm-pokymllib32-linux-gnueabi-llvm-ar-10 -> ar - auto I = Stem.rfind_lower(Tool); + auto I = Stem.rfind_insensitive(Tool); return I != StringRef::npos && (I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()])); };