diff options
| author | The rustc-josh-sync Cronjob Bot <github-actions@github.com> | 2025-09-25 04:16:26 +0000 |
|---|---|---|
| committer | The rustc-josh-sync Cronjob Bot <github-actions@github.com> | 2025-09-25 04:16:26 +0000 |
| commit | ff7e7319837d5029ed4f522601debc2a7bc33274 (patch) | |
| tree | 42dbcb2d8c347a2e7c97c7e4361b1c361143da0b /compiler/rustc_llvm/llvm-wrapper | |
| parent | 3280c210dd6e5f26595ff4857572f8feba678992 (diff) | |
| parent | d226e7aa93425ba2090f423642341a99ab047838 (diff) | |
| download | rust-ff7e7319837d5029ed4f522601debc2a7bc33274.tar.gz rust-ff7e7319837d5029ed4f522601debc2a7bc33274.zip | |
Merge ref 'caccb4d0368b' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: caccb4d0368bd918ef6668af8e13834d07040417 Filtered ref: 0f345ed05d559bbfb754f1403b16199366cda2e0 Upstream diff: https://github.com/rust-lang/rust/compare/21a19c297d4f5a03501d92ca251bd7a17073c08a...caccb4d0368bd918ef6668af8e13834d07040417 This merge was created using https://github.com/rust-lang/josh-sync.
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper')
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp | 208 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 309 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 216 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp | 99 |
4 files changed, 125 insertions, 707 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp deleted file mode 100644 index feac6a5649c..00000000000 --- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#include "LLVMWrapper.h" - -#include "llvm/Object/Archive.h" -#include "llvm/Object/ArchiveWriter.h" -#include "llvm/Support/Path.h" - -using namespace llvm; -using namespace llvm::object; - -struct RustArchiveMember { - const char *Filename; - const char *Name; - Archive::Child Child; - - RustArchiveMember() - : Filename(nullptr), Name(nullptr), Child(nullptr, nullptr, nullptr) {} - ~RustArchiveMember() {} -}; - -struct RustArchiveIterator { - bool First; - Archive::child_iterator Cur; - Archive::child_iterator End; - std::unique_ptr<Error> Err; - - RustArchiveIterator(Archive::child_iterator Cur, Archive::child_iterator End, - std::unique_ptr<Error> Err) - : First(true), Cur(Cur), End(End), Err(std::move(Err)) {} -}; - -enum class LLVMRustArchiveKind { - GNU, - BSD, - DARWIN, - COFF, - AIX_BIG, -}; - -static Archive::Kind fromRust(LLVMRustArchiveKind Kind) { - switch (Kind) { - case LLVMRustArchiveKind::GNU: - return Archive::K_GNU; - case LLVMRustArchiveKind::BSD: - return Archive::K_BSD; - case LLVMRustArchiveKind::DARWIN: - return Archive::K_DARWIN; - case LLVMRustArchiveKind::COFF: - return Archive::K_COFF; - case LLVMRustArchiveKind::AIX_BIG: - return Archive::K_AIXBIG; - default: - report_fatal_error("Bad ArchiveKind."); - } -} - -typedef OwningBinary<Archive> *LLVMRustArchiveRef; -typedef RustArchiveMember *LLVMRustArchiveMemberRef; -typedef Archive::Child *LLVMRustArchiveChildRef; -typedef Archive::Child const *LLVMRustArchiveChildConstRef; -typedef RustArchiveIterator *LLVMRustArchiveIteratorRef; - -extern "C" LLVMRustArchiveRef LLVMRustOpenArchive(char *Path) { - ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr = MemoryBuffer::getFile( - Path, /*IsText*/ false, /*RequiresNullTerminator=*/false); - if (!BufOr) { - LLVMRustSetLastError(BufOr.getError().message().c_str()); - return nullptr; - } - - Expected<std::unique_ptr<Archive>> ArchiveOr = - Archive::create(BufOr.get()->getMemBufferRef()); - - if (!ArchiveOr) { - LLVMRustSetLastError(toString(ArchiveOr.takeError()).c_str()); - return nullptr; - } - - OwningBinary<Archive> *Ret = new OwningBinary<Archive>( - std::move(ArchiveOr.get()), std::move(BufOr.get())); - - return Ret; -} - -extern "C" void LLVMRustDestroyArchive(LLVMRustArchiveRef RustArchive) { - delete RustArchive; -} - -extern "C" LLVMRustArchiveIteratorRef -LLVMRustArchiveIteratorNew(LLVMRustArchiveRef RustArchive) { - Archive *Archive = RustArchive->getBinary(); - std::unique_ptr<Error> Err = std::make_unique<Error>(Error::success()); - auto Cur = Archive->child_begin(*Err); - if (*Err) { - LLVMRustSetLastError(toString(std::move(*Err)).c_str()); - return nullptr; - } - auto End = Archive->child_end(); - return new RustArchiveIterator(Cur, End, std::move(Err)); -} - -extern "C" LLVMRustArchiveChildConstRef -LLVMRustArchiveIteratorNext(LLVMRustArchiveIteratorRef RAI) { - if (RAI->Cur == RAI->End) - return nullptr; - - // Advancing the iterator validates the next child, and this can - // uncover an error. LLVM requires that we check all Errors, - // so we only advance the iterator if we actually need to fetch - // the next child. - // This means we must not advance the iterator in the *first* call, - // but instead advance it *before* fetching the child in all later calls. - if (!RAI->First) { - ++RAI->Cur; - if (*RAI->Err) { - LLVMRustSetLastError(toString(std::move(*RAI->Err)).c_str()); - return nullptr; - } - } else { - RAI->First = false; - } - - if (RAI->Cur == RAI->End) - return nullptr; - - const Archive::Child &Child = *RAI->Cur.operator->(); - Archive::Child *Ret = new Archive::Child(Child); - - return Ret; -} - -extern "C" void LLVMRustArchiveChildFree(LLVMRustArchiveChildRef Child) { - delete Child; -} - -extern "C" void LLVMRustArchiveIteratorFree(LLVMRustArchiveIteratorRef RAI) { - delete RAI; -} - -extern "C" const char * -LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) { - Expected<StringRef> NameOrErr = Child->getName(); - if (!NameOrErr) { - // rustc_codegen_llvm currently doesn't use this error string, but it might - // be useful in the future, and in the meantime this tells LLVM that the - // error was not ignored and that it shouldn't abort the process. - LLVMRustSetLastError(toString(NameOrErr.takeError()).c_str()); - return nullptr; - } - StringRef Name = NameOrErr.get(); - *Size = Name.size(); - return Name.data(); -} - -extern "C" LLVMRustArchiveMemberRef -LLVMRustArchiveMemberNew(char *Filename, char *Name, - LLVMRustArchiveChildRef Child) { - RustArchiveMember *Member = new RustArchiveMember; - Member->Filename = Filename; - Member->Name = Name; - if (Child) - Member->Child = *Child; - return Member; -} - -extern "C" void LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) { - delete Member; -} - -extern "C" LLVMRustResult LLVMRustWriteArchive( - char *Dst, size_t NumMembers, const LLVMRustArchiveMemberRef *NewMembers, - bool WriteSymbtab, LLVMRustArchiveKind RustKind, bool isEC) { - - std::vector<NewArchiveMember> Members; - auto Kind = fromRust(RustKind); - - for (size_t I = 0; I < NumMembers; I++) { - auto Member = NewMembers[I]; - assert(Member->Name); - if (Member->Filename) { - Expected<NewArchiveMember> MOrErr = - NewArchiveMember::getFile(Member->Filename, true); - if (!MOrErr) { - LLVMRustSetLastError(toString(MOrErr.takeError()).c_str()); - return LLVMRustResult::Failure; - } - MOrErr->MemberName = sys::path::filename(MOrErr->MemberName); - Members.push_back(std::move(*MOrErr)); - } else { - Expected<NewArchiveMember> MOrErr = - NewArchiveMember::getOldMember(Member->Child, true); - if (!MOrErr) { - LLVMRustSetLastError(toString(MOrErr.takeError()).c_str()); - return LLVMRustResult::Failure; - } - Members.push_back(std::move(*MOrErr)); - } - } - - auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab - : SymtabWritingMode::NoSymtab; - auto Result = - writeArchive(Dst, Members, SymtabMode, Kind, true, false, nullptr, isEC); - if (!Result) - return LLVMRustResult::Success; - LLVMRustSetLastError(toString(std::move(Result)).c_str()); - - return LLVMRustResult::Failure; -} diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 8c34052770e..7518b40799b 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -79,122 +79,6 @@ extern "C" void LLVMRustTimeTraceProfilerFinish(const char *FileName) { timeTraceProfilerCleanup(); } -#ifdef LLVM_COMPONENT_X86 -#define SUBTARGET_X86 SUBTARGET(X86) -#else -#define SUBTARGET_X86 -#endif - -#ifdef LLVM_COMPONENT_ARM -#define SUBTARGET_ARM SUBTARGET(ARM) -#else -#define SUBTARGET_ARM -#endif - -#ifdef LLVM_COMPONENT_AARCH64 -#define SUBTARGET_AARCH64 SUBTARGET(AArch64) -#else -#define SUBTARGET_AARCH64 -#endif - -#ifdef LLVM_COMPONENT_AVR -#define SUBTARGET_AVR SUBTARGET(AVR) -#else -#define SUBTARGET_AVR -#endif - -#ifdef LLVM_COMPONENT_M68k -#define SUBTARGET_M68K SUBTARGET(M68k) -#else -#define SUBTARGET_M68K -#endif - -#ifdef LLVM_COMPONENT_CSKY -#define SUBTARGET_CSKY SUBTARGET(CSKY) -#else -#define SUBTARGET_CSKY -#endif - -#ifdef LLVM_COMPONENT_MIPS -#define SUBTARGET_MIPS SUBTARGET(Mips) -#else -#define SUBTARGET_MIPS -#endif - -#ifdef LLVM_COMPONENT_POWERPC -#define SUBTARGET_PPC SUBTARGET(PPC) -#else -#define SUBTARGET_PPC -#endif - -#ifdef LLVM_COMPONENT_SYSTEMZ -#define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ) -#else -#define SUBTARGET_SYSTEMZ -#endif - -#ifdef LLVM_COMPONENT_MSP430 -#define SUBTARGET_MSP430 SUBTARGET(MSP430) -#else -#define SUBTARGET_MSP430 -#endif - -#ifdef LLVM_COMPONENT_RISCV -#define SUBTARGET_RISCV SUBTARGET(RISCV) -#else -#define SUBTARGET_RISCV -#endif - -#ifdef LLVM_COMPONENT_SPARC -#define SUBTARGET_SPARC SUBTARGET(Sparc) -#else -#define SUBTARGET_SPARC -#endif - -#ifdef LLVM_COMPONENT_XTENSA -#define SUBTARGET_XTENSA SUBTARGET(XTENSA) -#else -#define SUBTARGET_XTENSA -#endif - -#ifdef LLVM_COMPONENT_HEXAGON -#define SUBTARGET_HEXAGON SUBTARGET(Hexagon) -#else -#define SUBTARGET_HEXAGON -#endif - -#ifdef LLVM_COMPONENT_LOONGARCH -#define SUBTARGET_LOONGARCH SUBTARGET(LoongArch) -#else -#define SUBTARGET_LOONGARCH -#endif - -#define GEN_SUBTARGETS \ - SUBTARGET_X86 \ - SUBTARGET_ARM \ - SUBTARGET_AARCH64 \ - SUBTARGET_AVR \ - SUBTARGET_M68K \ - SUBTARGET_CSKY \ - SUBTARGET_MIPS \ - SUBTARGET_PPC \ - SUBTARGET_SYSTEMZ \ - SUBTARGET_MSP430 \ - SUBTARGET_SPARC \ - SUBTARGET_HEXAGON \ - SUBTARGET_XTENSA \ - SUBTARGET_RISCV \ - SUBTARGET_LOONGARCH - -#define SUBTARGET(x) \ - namespace llvm { \ - extern const SubtargetFeatureKV x##FeatureKV[]; \ - extern const SubtargetFeatureKV x##SubTypeKV[]; \ - } - -GEN_SUBTARGETS -#undef SUBTARGET - // This struct and various functions are sort of a hack right now, but the // problem is that we've got in-memory LLVM modules after we generate and // optimize all codegen-units for one compilation in rustc. To be compatible @@ -340,14 +224,6 @@ static FloatABI::ABIType fromRust(LLVMRustFloatABI RustFloatAbi) { report_fatal_error("Bad FloatABI."); } -/// getLongestEntryLength - Return the length of the longest entry in the table. -template <typename KV> static size_t getLongestEntryLength(ArrayRef<KV> Table) { - size_t MaxLen = 0; - for (auto &I : Table) - MaxLen = std::max(MaxLen, std::strlen(I.Key)); - return MaxLen; -} - extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, RustStringRef OutStr) { ArrayRef<SubtargetSubTypeKV> CPUTable = @@ -395,8 +271,9 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool TrapUnreachable, bool Singlethread, bool VerboseAsm, bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, const char *SplitDwarfFile, const char *OutputObjFile, - const char *DebugInfoCompression, bool UseEmulatedTls, - const char *ArgsCstrBuff, size_t ArgsCstrBuffLen, bool UseWasmEH) { + const char *DebugInfoCompression, bool UseEmulatedTls, const char *Argv0, + size_t Argv0Len, const char *CommandLineArgs, size_t CommandLineArgsLen, + bool UseWasmEH) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -467,53 +344,10 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.EmitStackSizeSection = EmitStackSizeSection; - if (ArgsCstrBuff != nullptr) { -#if LLVM_VERSION_GE(20, 0) - size_t buffer_offset = 0; - assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0'); - auto Arg0 = std::string(ArgsCstrBuff); - buffer_offset = Arg0.size() + 1; - - std::string CommandlineArgs; - raw_string_ostream OS(CommandlineArgs); - ListSeparator LS(" "); - for (StringRef Arg : split(StringRef(ArgsCstrBuff + buffer_offset, - ArgsCstrBuffLen - buffer_offset), - '\0')) { - OS << LS; - sys::printArg(OS, Arg, /*Quote=*/true); - } - OS.flush(); - Options.MCOptions.Argv0 = Arg0; - Options.MCOptions.CommandlineArgs = CommandlineArgs; -#else - size_t buffer_offset = 0; - assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0'); - - const size_t arg0_len = std::strlen(ArgsCstrBuff); - char *arg0 = new char[arg0_len + 1]; - memcpy(arg0, ArgsCstrBuff, arg0_len); - arg0[arg0_len] = '\0'; - buffer_offset += arg0_len + 1; - - const size_t num_cmd_arg_strings = std::count( - &ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0'); - - std::string *cmd_arg_strings = new std::string[num_cmd_arg_strings]; - for (size_t i = 0; i < num_cmd_arg_strings; ++i) { - assert(buffer_offset < ArgsCstrBuffLen); - const size_t len = std::strlen(ArgsCstrBuff + buffer_offset); - cmd_arg_strings[i] = std::string(&ArgsCstrBuff[buffer_offset], len); - buffer_offset += len + 1; - } - - assert(buffer_offset == ArgsCstrBuffLen); - - Options.MCOptions.Argv0 = arg0; - Options.MCOptions.CommandLineArgs = - llvm::ArrayRef<std::string>(cmd_arg_strings, num_cmd_arg_strings); -#endif - } + if (Argv0 != nullptr) + Options.MCOptions.Argv0 = {Argv0, Argv0Len}; + if (CommandLineArgs != nullptr) + Options.MCOptions.CommandlineArgs = {CommandLineArgs, CommandLineArgsLen}; #if LLVM_VERSION_GE(21, 0) TargetMachine *TM = TheTarget->createTargetMachine(Trip, CPU, Feature, @@ -526,12 +360,6 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( } extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) { -#if LLVM_VERSION_LT(20, 0) - MCTargetOptions &MCOptions = unwrap(TM)->Options.MCOptions; - delete[] MCOptions.Argv0; - delete[] MCOptions.CommandLineArgs.data(); -#endif - delete unwrap(TM); } @@ -812,14 +640,9 @@ extern "C" LLVMRustResult LLVMRustOptimize( // the PassBuilder does not create a pipeline. std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>> PipelineStartEPCallbacks; -#if LLVM_VERSION_GE(20, 0) std::vector<std::function<void(ModulePassManager &, OptimizationLevel, ThinOrFullLTOPhase)>> OptimizerLastEPCallbacks; -#else - std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>> - OptimizerLastEPCallbacks; -#endif if (!IsLinkerPluginLTO && SanitizerOptions && SanitizerOptions->SanitizeCFI && !NoPrepopulatePasses) { @@ -871,12 +694,8 @@ extern "C" LLVMRustResult LLVMRustOptimize( SanitizerOptions->SanitizeDataFlowABIList + SanitizerOptions->SanitizeDataFlowABIListLen); OptimizerLastEPCallbacks.push_back( -#if LLVM_VERSION_GE(20, 0) [ABIListFiles](ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase phase) { -#else - [ABIListFiles](ModulePassManager &MPM, OptimizationLevel Level) { -#endif MPM.addPass(DataFlowSanitizerPass(ABIListFiles)); }); } @@ -887,66 +706,48 @@ extern "C" LLVMRustResult LLVMRustOptimize( SanitizerOptions->SanitizeMemoryRecover, /*CompileKernel=*/false, /*EagerChecks=*/true); - OptimizerLastEPCallbacks.push_back( -#if LLVM_VERSION_GE(20, 0) - [Options](ModulePassManager &MPM, OptimizationLevel Level, - ThinOrFullLTOPhase phase) { -#else - [Options](ModulePassManager &MPM, OptimizationLevel Level) { -#endif - MPM.addPass(MemorySanitizerPass(Options)); - }); + OptimizerLastEPCallbacks.push_back([Options](ModulePassManager &MPM, + OptimizationLevel Level, + ThinOrFullLTOPhase phase) { + MPM.addPass(MemorySanitizerPass(Options)); + }); } if (SanitizerOptions->SanitizeThread) { - OptimizerLastEPCallbacks.push_back( -#if LLVM_VERSION_GE(20, 0) - [](ModulePassManager &MPM, OptimizationLevel Level, - ThinOrFullLTOPhase phase) { -#else - [](ModulePassManager &MPM, OptimizationLevel Level) { -#endif - MPM.addPass(ModuleThreadSanitizerPass()); - MPM.addPass( - createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); - }); + OptimizerLastEPCallbacks.push_back([](ModulePassManager &MPM, + OptimizationLevel Level, + ThinOrFullLTOPhase phase) { + MPM.addPass(ModuleThreadSanitizerPass()); + MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); + }); } if (SanitizerOptions->SanitizeAddress || SanitizerOptions->SanitizeKernelAddress) { - OptimizerLastEPCallbacks.push_back( -#if LLVM_VERSION_GE(20, 0) - [SanitizerOptions, TM](ModulePassManager &MPM, - OptimizationLevel Level, - ThinOrFullLTOPhase phase) { -#else - [SanitizerOptions, TM](ModulePassManager &MPM, - OptimizationLevel Level) { -#endif - auto CompileKernel = SanitizerOptions->SanitizeKernelAddress; - AddressSanitizerOptions opts = AddressSanitizerOptions{ - CompileKernel, - SanitizerOptions->SanitizeAddressRecover || - SanitizerOptions->SanitizeKernelAddressRecover, - /*UseAfterScope=*/true, - AsanDetectStackUseAfterReturnMode::Runtime, - }; - MPM.addPass(AddressSanitizerPass( - opts, - /*UseGlobalGC*/ true, - // UseOdrIndicator should be false on windows machines - // https://reviews.llvm.org/D137227 - !TM->getTargetTriple().isOSWindows())); - }); + OptimizerLastEPCallbacks.push_back([SanitizerOptions, + TM](ModulePassManager &MPM, + OptimizationLevel Level, + ThinOrFullLTOPhase phase) { + auto CompileKernel = SanitizerOptions->SanitizeKernelAddress; + AddressSanitizerOptions opts = AddressSanitizerOptions{ + CompileKernel, + SanitizerOptions->SanitizeAddressRecover || + SanitizerOptions->SanitizeKernelAddressRecover, + /*UseAfterScope=*/true, + AsanDetectStackUseAfterReturnMode::Runtime, + }; + MPM.addPass( + AddressSanitizerPass(opts, + /*UseGlobalGC*/ true, + // UseOdrIndicator should be false on windows + // machines https://reviews.llvm.org/D137227 + !TM->getTargetTriple().isOSWindows())); + }); } if (SanitizerOptions->SanitizeHWAddress) { OptimizerLastEPCallbacks.push_back( -#if LLVM_VERSION_GE(20, 0) [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase phase) { -#else - [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) { -#endif HWAddressSanitizerOptions opts( /*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover, @@ -1028,11 +829,7 @@ extern "C" LLVMRustResult LLVMRustOptimize( for (const auto &C : PipelineStartEPCallbacks) C(MPM, OptLevel); for (const auto &C : OptimizerLastEPCallbacks) -#if LLVM_VERSION_GE(20, 0) C(MPM, OptLevel, ThinOrFullLTOPhase::None); -#else - C(MPM, OptLevel); -#endif } if (ExtraPassesLen) { @@ -1226,12 +1023,6 @@ extern "C" void LLVMRustPrintPasses() { extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols, size_t Len) { auto PreserveFunctions = [=](const GlobalValue &GV) { - // Preserve LLVM-injected, ASAN-related symbols. - // See also https://github.com/rust-lang/rust/issues/113404. - if (GV.getName() == "___asan_globals_registered") { - return true; - } - // Preserve symbols exported from Rust modules. for (size_t I = 0; I < Len; I++) { if (GV.getName() == Symbols[I]) { @@ -1315,11 +1106,7 @@ struct LLVMRustThinLTOData { // Not 100% sure what these are, but they impact what's internalized and // what's inlined across modules, I believe. -#if LLVM_VERSION_GE(20, 0) FunctionImporter::ImportListsTy ImportLists; -#else - DenseMap<StringRef, FunctionImporter::ImportMapTy> ImportLists; -#endif DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists; DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries; StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR; @@ -1574,12 +1361,11 @@ extern "C" bool LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, return true; } -extern "C" LLVMRustThinLTOBuffer * -LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin, bool emit_summary) { +extern "C" LLVMRustThinLTOBuffer *LLVMRustThinLTOBufferCreate(LLVMModuleRef M, + bool is_thin) { auto Ret = std::make_unique<LLVMRustThinLTOBuffer>(); { auto OS = raw_string_ostream(Ret->data); - auto ThinLinkOS = raw_string_ostream(Ret->thin_link_data); { if (is_thin) { PassBuilder PB; @@ -1593,11 +1379,7 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin, bool emit_summary) { PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); ModulePassManager MPM; - // We only pass ThinLinkOS to be filled in if we want the summary, - // because otherwise LLVM does extra work and may double-emit some - // errors or warnings. - MPM.addPass( - ThinLTOBitcodeWriterPass(OS, emit_summary ? &ThinLinkOS : nullptr)); + MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr)); MPM.run(*unwrap(M), MAM); } else { WriteBitcodeToFile(*unwrap(M), OS); @@ -1666,13 +1448,8 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut, const auto &ExportList = Data->ExportLists.lookup(ModId); const auto &ResolvedODR = Data->ResolvedODR.lookup(ModId); const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(ModId); -#if LLVM_VERSION_GE(20, 0) DenseSet<GlobalValue::GUID> CfiFunctionDefs; DenseSet<GlobalValue::GUID> CfiFunctionDecls; -#else - std::set<GlobalValue::GUID> CfiFunctionDefs; - std::set<GlobalValue::GUID> CfiFunctionDecls; -#endif // Based on the 'InProcessThinBackend' constructor in LLVM #if LLVM_VERSION_GE(21, 0) @@ -1691,15 +1468,9 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut, GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name))); #endif -#if LLVM_VERSION_GE(20, 0) Key = llvm::computeLTOCacheKey(conf, Data->Index, ModId, ImportList, ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls); -#else - llvm::computeLTOCacheKey(Key, conf, Data->Index, ModId, ImportList, - ExportList, ResolvedODR, DefinedGlobals, - CfiFunctionDefs, CfiFunctionDecls); -#endif auto OS = RawRustStringOstream(KeyOut); OS << Key.str(); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 588d867bbbf..414274f24fb 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -242,7 +242,7 @@ enum class LLVMRustAttributeKind { MinSize = 4, Naked = 5, NoAlias = 6, - NoCapture = 7, + CapturesAddress = 7, NoInline = 8, NonNull = 9, NoRedZone = 10, @@ -277,6 +277,8 @@ enum class LLVMRustAttributeKind { FnRetThunkExtern = 41, Writable = 42, DeadOnUnwind = 43, + DeadOnReturn = 44, + CapturesReadOnly = 45, }; static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) { @@ -295,12 +297,6 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) { return Attribute::Naked; case LLVMRustAttributeKind::NoAlias: return Attribute::NoAlias; - case LLVMRustAttributeKind::NoCapture: -#if LLVM_VERSION_GE(21, 0) - report_fatal_error("NoCapture doesn't exist in LLVM 21"); -#else - return Attribute::NoCapture; -#endif case LLVMRustAttributeKind::NoCfCheck: return Attribute::NoCfCheck; case LLVMRustAttributeKind::NoInline: @@ -369,6 +365,15 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) { return Attribute::Writable; case LLVMRustAttributeKind::DeadOnUnwind: return Attribute::DeadOnUnwind; + case LLVMRustAttributeKind::DeadOnReturn: +#if LLVM_VERSION_GE(21, 0) + return Attribute::DeadOnReturn; +#else + report_fatal_error("DeadOnReturn attribute requires LLVM 21 or later"); +#endif + case LLVMRustAttributeKind::CapturesAddress: + case LLVMRustAttributeKind::CapturesReadOnly: + report_fatal_error("Should be handled separately"); } report_fatal_error("bad LLVMRustAttributeKind"); } @@ -419,9 +424,14 @@ extern "C" void LLVMRustEraseInstFromParent(LLVMValueRef Instr) { extern "C" LLVMAttributeRef LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttributeKind RustAttr) { #if LLVM_VERSION_GE(21, 0) - // LLVM 21 replaced the NoCapture attribute with Captures(none). - if (RustAttr == LLVMRustAttributeKind::NoCapture) { - return wrap(Attribute::getWithCaptureInfo(*unwrap(C), CaptureInfo::none())); + if (RustAttr == LLVMRustAttributeKind::CapturesAddress) { + return wrap(Attribute::getWithCaptureInfo( + *unwrap(C), CaptureInfo(CaptureComponents::Address))); + } + if (RustAttr == LLVMRustAttributeKind::CapturesReadOnly) { + return wrap(Attribute::getWithCaptureInfo( + *unwrap(C), CaptureInfo(CaptureComponents::Address | + CaptureComponents::ReadProvenance))); } #endif return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr))); @@ -473,6 +483,9 @@ extern "C" LLVMAttributeRef LLVMRustCreateRangeAttribute(LLVMContextRef C, unsigned NumBits, const uint64_t LowerWords[], const uint64_t UpperWords[]) { + // FIXME(Zalathar): There appears to be no stable guarantee that C++ + // `AttrKind` values correspond directly to the `unsigned KindID` values + // accepted by LLVM-C API functions, though in practice they currently do. return LLVMCreateConstantRangeAttribute(C, Attribute::Range, NumBits, LowerWords, UpperWords); } @@ -540,6 +553,7 @@ enum class LLVMRustMemoryEffects { None, ReadOnly, InaccessibleMemOnly, + ReadOnlyNotPure, }; extern "C" LLVMAttributeRef @@ -555,6 +569,10 @@ LLVMRustCreateMemoryEffectsAttr(LLVMContextRef C, case LLVMRustMemoryEffects::InaccessibleMemOnly: return wrap(Attribute::getWithMemoryEffects( *unwrap(C), MemoryEffects::inaccessibleMemOnly())); + case LLVMRustMemoryEffects::ReadOnlyNotPure: + return wrap(Attribute::getWithMemoryEffects( + *unwrap(C), + MemoryEffects::readOnly() | MemoryEffects::inaccessibleMemOnly())); default: report_fatal_error("bad MemoryEffects."); } @@ -1013,13 +1031,6 @@ LLVMRustDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename, CSInfo, oSource)); } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder, - LLVMMetadataRef ParameterTypes) { - return wrap(unwrap(Builder)->createSubroutineType( - DITypeRefArray(unwrap<MDTuple>(ParameterTypes)))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, @@ -1058,47 +1069,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod( return wrap(Sub); } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name, - size_t NameLen, uint64_t SizeInBits, - unsigned Encoding) { - return wrap(unwrap(Builder)->createBasicType(StringRef(Name, NameLen), - SizeInBits, Encoding)); -} - -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type, - const char *Name, size_t NameLen, - LLVMMetadataRef File, unsigned LineNo, - LLVMMetadataRef Scope) { - return wrap(unwrap(Builder)->createTypedef( - unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File), - LineNo, unwrapDIPtr<DIScope>(Scope))); -} - -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType( - LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned AddressSpace, const char *Name, - size_t NameLen) { - return wrap(unwrap(Builder)->createPointerType( - unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, AddressSpace, - StringRef(Name, NameLen))); -} - -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType( - LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, - uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, - LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements, unsigned RunTimeLang, - LLVMMetadataRef VTableHolder, const char *UniqueId, size_t UniqueIdLen) { - return wrap(unwrap(Builder)->createStructType( - unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), - unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits, - fromRust(Flags), unwrapDI<DIType>(DerivedFrom), - DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang, - unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, @@ -1113,17 +1083,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart( StringRef(UniqueId, UniqueIdLen))); } -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType( - LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags, - LLVMMetadataRef Ty) { - return wrap(unwrap(Builder)->createMemberType( - unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), - unwrapDI<DIFile>(File), LineNo, SizeInBits, AlignInBits, OffsetInBits, - fromRust(Flags), unwrapDI<DIType>(Ty))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits, @@ -1139,23 +1098,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType( fromRust(Flags), unwrapDI<DIType>(Ty))); } -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType( - LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, - LLVMDIFlags Flags, LLVMValueRef val, uint32_t AlignInBits) { - return wrap(unwrap(Builder)->createStaticMemberType( - unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), - unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), fromRust(Flags), - unwrap<llvm::ConstantInt>(val), llvm::dwarf::DW_TAG_member, AlignInBits)); -} - -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag, - LLVMMetadataRef Type) { - return wrap( - unwrap(Builder)->createQualifiedType(Tag, unwrapDI<DIType>(Type))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( LLVMDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, @@ -1206,15 +1148,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable( } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size, - uint32_t AlignInBits, LLVMMetadataRef Ty, - LLVMMetadataRef Subscripts) { - return wrap(unwrap(Builder)->createArrayType( - Size, AlignInBits, unwrapDI<DIType>(Ty), - DINodeArray(unwrapDI<MDTuple>(Subscripts)))); -} - -extern "C" LLVMMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Builder, int64_t Lo, int64_t Count) { return wrap(unwrap(Builder)->getOrCreateSubrange(Lo, Count)); @@ -1262,19 +1195,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( /* RunTimeLang */ 0, "", IsScoped)); } -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType( - LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, - uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, - LLVMMetadataRef Elements, unsigned RunTimeLang, const char *UniqueId, - size_t UniqueIdLen) { - return wrap(unwrap(Builder)->createUnionType( - unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), - unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits, - fromRust(Flags), DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang, - StringRef(UniqueId, UniqueIdLen))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef Ty) { @@ -1453,60 +1373,6 @@ LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) { return toRust((DiagnosticKind)unwrap(DI)->getKind()); } -// This is kept distinct from LLVMGetTypeKind, because when -// a new type kind is added, the Rust-side enum must be -// updated or UB will result. -extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) { - switch (unwrap(Ty)->getTypeID()) { - case Type::VoidTyID: - return LLVMVoidTypeKind; - case Type::HalfTyID: - return LLVMHalfTypeKind; - case Type::FloatTyID: - return LLVMFloatTypeKind; - case Type::DoubleTyID: - return LLVMDoubleTypeKind; - case Type::X86_FP80TyID: - return LLVMX86_FP80TypeKind; - case Type::FP128TyID: - return LLVMFP128TypeKind; - case Type::PPC_FP128TyID: - return LLVMPPC_FP128TypeKind; - case Type::LabelTyID: - return LLVMLabelTypeKind; - case Type::MetadataTyID: - return LLVMMetadataTypeKind; - case Type::IntegerTyID: - return LLVMIntegerTypeKind; - case Type::FunctionTyID: - return LLVMFunctionTypeKind; - case Type::StructTyID: - return LLVMStructTypeKind; - case Type::ArrayTyID: - return LLVMArrayTypeKind; - case Type::PointerTyID: - return LLVMPointerTypeKind; - case Type::FixedVectorTyID: - return LLVMVectorTypeKind; - case Type::TokenTyID: - return LLVMTokenTypeKind; - case Type::ScalableVectorTyID: - return LLVMScalableVectorTypeKind; - case Type::BFloatTyID: - return LLVMBFloatTypeKind; - case Type::X86_AMXTyID: - return LLVMX86_AMXTypeKind; - default: { - std::string error; - auto stream = llvm::raw_string_ostream(error); - stream << "Rust does not support the TypeID: " << unwrap(Ty)->getTypeID() - << " for the type: " << *unwrap(Ty); - stream.flush(); - report_fatal_error(error.c_str()); - } - } -} - DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef) extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(LLVMDiagnosticInfoRef DI, @@ -1986,29 +1852,3 @@ extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) { MD.NoHWAddress = true; GV.setSanitizerMetadata(MD); } - -enum class LLVMRustTailCallKind { - None = 0, - Tail = 1, - MustTail = 2, - NoTail = 3 -}; - -extern "C" void LLVMRustSetTailCallKind(LLVMValueRef Call, - LLVMRustTailCallKind Kind) { - CallInst *CI = unwrap<CallInst>(Call); - switch (Kind) { - case LLVMRustTailCallKind::None: - CI->setTailCallKind(CallInst::TCK_None); - break; - case LLVMRustTailCallKind::Tail: - CI->setTailCallKind(CallInst::TCK_Tail); - break; - case LLVMRustTailCallKind::MustTail: - CI->setTailCallKind(CallInst::TCK_MustTail); - break; - case LLVMRustTailCallKind::NoTail: - CI->setTailCallKind(CallInst::TCK_NoTail); - break; - } -} diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp index a910e78d489..fccfff65cfc 100644 --- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp @@ -103,14 +103,14 @@ LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State, #define TRUE_PTR (void *)1 #define FALSE_PTR (void *)0 -extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) { +bool withBufferAsSymbolicFile( + char *BufPtr, size_t BufLen, + std::function<bool(object::SymbolicFile &)> Callback) { std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer( StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false); SmallString<0> SymNameBuf; auto SymName = raw_svector_ostream(SymNameBuf); - // Code starting from this line is copied from s64BitSymbolicFile in - // ArchiveWriter.cpp. // In the scenario when LLVMContext is populated SymbolicFile will contain a // reference to it, thus SymbolicFile should be destroyed first. LLVMContext Context; @@ -120,48 +120,63 @@ extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) { return false; } std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr); - - return Obj != nullptr ? Obj->is64Bit() : false; -} - -extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) { - std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer( - StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false); - SmallString<0> SymNameBuf; - auto SymName = raw_svector_ostream(SymNameBuf); - - // In the scenario when LLVMContext is populated SymbolicFile will contain a - // reference to it, thus SymbolicFile should be destroyed first. - LLVMContext Context; - Expected<std::unique_ptr<object::SymbolicFile>> ObjOrErr = - getSymbolicFile(Buf->getMemBufferRef(), Context); - if (!ObjOrErr) { - return false; - } - std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr); - if (Obj == nullptr) { return false; } + return Callback(*Obj); +} - // Code starting from this line is copied from isECObject in - // ArchiveWriter.cpp with an extra #if to work with LLVM 17. - if (Obj->isCOFF()) - return cast<llvm::object::COFFObjectFile>(&*Obj)->getMachine() != - COFF::IMAGE_FILE_MACHINE_ARM64; - - if (Obj->isCOFFImportFile()) - return cast<llvm::object::COFFImportFile>(&*Obj)->getMachine() != - COFF::IMAGE_FILE_MACHINE_ARM64; - - if (Obj->isIR()) { - Expected<std::string> TripleStr = - getBitcodeTargetTriple(Obj->getMemoryBufferRef()); - if (!TripleStr) - return false; - Triple T(*TripleStr); - return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64; - } +extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) { + return withBufferAsSymbolicFile( + BufPtr, BufLen, [](object::SymbolicFile &Obj) { return Obj.is64Bit(); }); +} + +extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) { + return withBufferAsSymbolicFile( + BufPtr, BufLen, [](object::SymbolicFile &Obj) { + // Code starting from this line is copied from isECObject in + // ArchiveWriter.cpp with an extra #if to work with LLVM 17. + if (Obj.isCOFF()) + return cast<llvm::object::COFFObjectFile>(&Obj)->getMachine() != + COFF::IMAGE_FILE_MACHINE_ARM64; + + if (Obj.isCOFFImportFile()) + return cast<llvm::object::COFFImportFile>(&Obj)->getMachine() != + COFF::IMAGE_FILE_MACHINE_ARM64; + + if (Obj.isIR()) { + Expected<std::string> TripleStr = + getBitcodeTargetTriple(Obj.getMemoryBufferRef()); + if (!TripleStr) + return false; + Triple T(*TripleStr); + return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64; + } + + return false; + }); +} - return false; +extern "C" bool LLVMRustIsAnyArm64Coff(char *BufPtr, size_t BufLen) { + return withBufferAsSymbolicFile( + BufPtr, BufLen, [](object::SymbolicFile &Obj) { + // Code starting from this line is copied from isAnyArm64COFF in + // ArchiveWriter.cpp. + if (Obj.isCOFF()) + return COFF::isAnyArm64(cast<COFFObjectFile>(&Obj)->getMachine()); + + if (Obj.isCOFFImportFile()) + return COFF::isAnyArm64(cast<COFFImportFile>(&Obj)->getMachine()); + + if (Obj.isIR()) { + Expected<std::string> TripleStr = + getBitcodeTargetTriple(Obj.getMemoryBufferRef()); + if (!TripleStr) + return false; + Triple T(*TripleStr); + return T.isOSWindows() && T.getArch() == Triple::aarch64; + } + + return false; + }); } |
