Merge llvm-project release/14.x llvmorg-14.0.0-rc1-74-g4dc3cb8e3255
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-14.0.0-rc1-74-g4dc3cb8e3255. PR: 261742 MFC after: 2 weeks
This commit is contained in:
commit
d56accc7c3
@ -1625,50 +1625,50 @@ LANGBUILTIN(__builtin_coro_suspend, "cIb", "n", COR_LANG)
|
||||
|
||||
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
|
||||
// We need the generic prototype, since the packet type could be anything.
|
||||
LANGBUILTIN(read_pipe, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(write_pipe, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(read_pipe, "i.", "tn", OCL_PIPE)
|
||||
LANGBUILTIN(write_pipe, "i.", "tn", OCL_PIPE)
|
||||
|
||||
LANGBUILTIN(reserve_read_pipe, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(reserve_write_pipe, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(reserve_read_pipe, "i.", "tn", OCL_PIPE)
|
||||
LANGBUILTIN(reserve_write_pipe, "i.", "tn", OCL_PIPE)
|
||||
|
||||
LANGBUILTIN(commit_write_pipe, "v.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(commit_read_pipe, "v.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(commit_write_pipe, "v.", "tn", OCL_PIPE)
|
||||
LANGBUILTIN(commit_read_pipe, "v.", "tn", OCL_PIPE)
|
||||
|
||||
LANGBUILTIN(sub_group_reserve_read_pipe, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(sub_group_reserve_write_pipe, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(sub_group_reserve_read_pipe, "i.", "tn", OCL_PIPE)
|
||||
LANGBUILTIN(sub_group_reserve_write_pipe, "i.", "tn", OCL_PIPE)
|
||||
|
||||
LANGBUILTIN(sub_group_commit_read_pipe, "v.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(sub_group_commit_write_pipe, "v.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(sub_group_commit_read_pipe, "v.", "tn", OCL_PIPE)
|
||||
LANGBUILTIN(sub_group_commit_write_pipe, "v.", "tn", OCL_PIPE)
|
||||
|
||||
LANGBUILTIN(work_group_reserve_read_pipe, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(work_group_reserve_write_pipe, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(work_group_reserve_read_pipe, "i.", "tn", OCL_PIPE)
|
||||
LANGBUILTIN(work_group_reserve_write_pipe, "i.", "tn", OCL_PIPE)
|
||||
|
||||
LANGBUILTIN(work_group_commit_read_pipe, "v.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(work_group_commit_write_pipe, "v.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(work_group_commit_read_pipe, "v.", "tn", OCL_PIPE)
|
||||
LANGBUILTIN(work_group_commit_write_pipe, "v.", "tn", OCL_PIPE)
|
||||
|
||||
LANGBUILTIN(get_pipe_num_packets, "Ui.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_pipe_max_packets, "Ui.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_pipe_num_packets, "Ui.", "tn", OCL_PIPE)
|
||||
LANGBUILTIN(get_pipe_max_packets, "Ui.", "tn", OCL_PIPE)
|
||||
|
||||
// OpenCL v2.0 s6.13.17 - Enqueue kernel functions.
|
||||
// Custom builtin check allows to perform special check of passed block arguments.
|
||||
LANGBUILTIN(enqueue_kernel, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_work_group_size, "Ui.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "Ui.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_max_sub_group_size_for_ndrange, "Ui.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_sub_group_count_for_ndrange, "Ui.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(enqueue_kernel, "i.", "tn", OCL_DSE)
|
||||
LANGBUILTIN(get_kernel_work_group_size, "Ui.", "tn", OCL_DSE)
|
||||
LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "Ui.", "tn", OCL_DSE)
|
||||
LANGBUILTIN(get_kernel_max_sub_group_size_for_ndrange, "Ui.", "tn", OCL_DSE)
|
||||
LANGBUILTIN(get_kernel_sub_group_count_for_ndrange, "Ui.", "tn", OCL_DSE)
|
||||
|
||||
// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
|
||||
// FIXME: Pointer parameters of OpenCL builtins should have their address space
|
||||
// requirement defined.
|
||||
LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(to_global, "v*v*", "tn", OCL_GAS)
|
||||
LANGBUILTIN(to_local, "v*v*", "tn", OCL_GAS)
|
||||
LANGBUILTIN(to_private, "v*v*", "tn", OCL_GAS)
|
||||
|
||||
// OpenCL half load/store builtin
|
||||
LANGBUILTIN(__builtin_store_half, "vdh*", "n", ALL_OCLC_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_store_halff, "vfh*", "n", ALL_OCLC_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_load_half, "dhC*", "nc", ALL_OCLC_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_load_halff, "fhC*", "nc", ALL_OCLC_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_store_half, "vdh*", "n", ALL_OCL_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_store_halff, "vfh*", "n", ALL_OCL_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_load_half, "dhC*", "nc", ALL_OCL_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_load_halff, "fhC*", "nc", ALL_OCL_LANGUAGES)
|
||||
|
||||
// Builtins for os_log/os_trace
|
||||
BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut")
|
||||
|
@ -28,20 +28,21 @@ class IdentifierTable;
|
||||
class LangOptions;
|
||||
|
||||
enum LanguageID {
|
||||
GNU_LANG = 0x1, // builtin requires GNU mode.
|
||||
C_LANG = 0x2, // builtin for c only.
|
||||
CXX_LANG = 0x4, // builtin for cplusplus only.
|
||||
OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
|
||||
MS_LANG = 0x10, // builtin requires MS mode.
|
||||
OCLC20_LANG = 0x20, // builtin for OpenCL C 2.0 only.
|
||||
OCLC1X_LANG = 0x40, // builtin for OpenCL C 1.x only.
|
||||
OMP_LANG = 0x80, // builtin requires OpenMP.
|
||||
CUDA_LANG = 0x100, // builtin requires CUDA.
|
||||
COR_LANG = 0x200, // builtin requires use of 'fcoroutine-ts' option.
|
||||
GNU_LANG = 0x1, // builtin requires GNU mode.
|
||||
C_LANG = 0x2, // builtin for c only.
|
||||
CXX_LANG = 0x4, // builtin for cplusplus only.
|
||||
OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
|
||||
MS_LANG = 0x10, // builtin requires MS mode.
|
||||
OMP_LANG = 0x20, // builtin requires OpenMP.
|
||||
CUDA_LANG = 0x40, // builtin requires CUDA.
|
||||
COR_LANG = 0x80, // builtin requires use of 'fcoroutine-ts' option.
|
||||
OCL_GAS = 0x100, // builtin requires OpenCL generic address space.
|
||||
OCL_PIPE = 0x200, // builtin requires OpenCL pipe.
|
||||
OCL_DSE = 0x400, // builtin requires OpenCL device side enqueue.
|
||||
ALL_OCL_LANGUAGES = 0x800, // builtin for OCL languages.
|
||||
ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
|
||||
ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode.
|
||||
ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG, // builtin requires MS mode.
|
||||
ALL_OCLC_LANGUAGES = OCLC1X_LANG | OCLC20_LANG // builtin for OCLC languages.
|
||||
ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode.
|
||||
};
|
||||
|
||||
namespace Builtin {
|
||||
|
@ -145,8 +145,8 @@ def warn_conflicting_nullability_attr_overriding_param_types : Warning<
|
||||
def err_nullability_conflicting : Error<
|
||||
"nullability specifier %0 conflicts with existing specifier %1">;
|
||||
|
||||
def warn_target_unsupported_branch_protection_option: Warning <
|
||||
"ignoring '-mbranch-protection=' option because the '%0' architecture does not support it">,
|
||||
def warn_incompatible_branch_protection_option: Warning <
|
||||
"'-mbranch-protection=' option is incompatible with the '%0' architecture">,
|
||||
InGroup<BranchProtection>;
|
||||
|
||||
def warn_target_unsupported_branch_protection_attribute: Warning <
|
||||
|
@ -644,8 +644,8 @@ class TargetInfo : public virtual TransferrableTargetInfo,
|
||||
}
|
||||
|
||||
/// Return the largest alignment for which a suitably-sized allocation with
|
||||
/// '::operator new(size_t)' or 'malloc' is guaranteed to produce a
|
||||
/// correctly-aligned pointer.
|
||||
/// '::operator new(size_t)' is guaranteed to produce a correctly-aligned
|
||||
/// pointer.
|
||||
unsigned getNewAlign() const {
|
||||
return NewAlign ? NewAlign : std::max(LongDoubleAlign, LongLongAlign);
|
||||
}
|
||||
|
@ -69,22 +69,26 @@ bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo,
|
||||
bool MSModeUnsupported =
|
||||
!LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG);
|
||||
bool ObjCUnsupported = !LangOpts.ObjC && BuiltinInfo.Langs == OBJC_LANG;
|
||||
bool OclC1Unsupported = (LangOpts.OpenCLVersion / 100) != 1 &&
|
||||
(BuiltinInfo.Langs & ALL_OCLC_LANGUAGES ) == OCLC1X_LANG;
|
||||
bool OclC2Unsupported =
|
||||
(LangOpts.getOpenCLCompatibleVersion() != 200) &&
|
||||
(BuiltinInfo.Langs & ALL_OCLC_LANGUAGES) == OCLC20_LANG;
|
||||
bool OclCUnsupported = !LangOpts.OpenCL &&
|
||||
(BuiltinInfo.Langs & ALL_OCLC_LANGUAGES);
|
||||
bool OclCUnsupported =
|
||||
!LangOpts.OpenCL && (BuiltinInfo.Langs & ALL_OCL_LANGUAGES);
|
||||
bool OclGASUnsupported =
|
||||
!LangOpts.OpenCLGenericAddressSpace && (BuiltinInfo.Langs & OCL_GAS);
|
||||
bool OclPipeUnsupported =
|
||||
!LangOpts.OpenCLPipes && (BuiltinInfo.Langs & OCL_PIPE);
|
||||
// Device side enqueue is not supported until OpenCL 2.0. In 2.0 and higher
|
||||
// support is indicated with language option for blocks.
|
||||
bool OclDSEUnsupported =
|
||||
(LangOpts.getOpenCLCompatibleVersion() < 200 || !LangOpts.Blocks) &&
|
||||
(BuiltinInfo.Langs & OCL_DSE);
|
||||
bool OpenMPUnsupported = !LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG;
|
||||
bool CUDAUnsupported = !LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG;
|
||||
bool CPlusPlusUnsupported =
|
||||
!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG;
|
||||
return !BuiltinsUnsupported && !CorBuiltinsUnsupported &&
|
||||
!MathBuiltinsUnsupported && !OclCUnsupported && !OclC1Unsupported &&
|
||||
!OclC2Unsupported && !OpenMPUnsupported && !GnuModeUnsupported &&
|
||||
!MSModeUnsupported && !ObjCUnsupported && !CPlusPlusUnsupported &&
|
||||
!CUDAUnsupported;
|
||||
!MathBuiltinsUnsupported && !OclCUnsupported && !OclGASUnsupported &&
|
||||
!OclPipeUnsupported && !OclDSEUnsupported && !OpenMPUnsupported &&
|
||||
!GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported &&
|
||||
!CPlusPlusUnsupported && !CUDAUnsupported;
|
||||
}
|
||||
|
||||
/// initializeBuiltins - Mark the identifiers for all the builtins with their
|
||||
|
@ -4381,6 +4381,14 @@ LangAS CodeGenModule::GetGlobalConstantAddressSpace() const {
|
||||
return LangAS::opencl_constant;
|
||||
if (LangOpts.SYCLIsDevice)
|
||||
return LangAS::sycl_global;
|
||||
if (LangOpts.HIP && LangOpts.CUDAIsDevice && getTriple().isSPIRV())
|
||||
// For HIPSPV map literals to cuda_device (maps to CrossWorkGroup in SPIR-V)
|
||||
// instead of default AS (maps to Generic in SPIR-V). Otherwise, we end up
|
||||
// with OpVariable instructions with Generic storage class which is not
|
||||
// allowed (SPIR-V V1.6 s3.42.8). Also, mapping literals to SPIR-V
|
||||
// UniformConstant storage class is not viable as pointers to it may not be
|
||||
// casted to Generic pointers which are used to model HIP's "flat" pointers.
|
||||
return LangAS::cuda_device;
|
||||
if (auto AS = getTarget().getConstantAddressSpace())
|
||||
return AS.getValue();
|
||||
return LangAS::Default;
|
||||
|
@ -9474,6 +9474,28 @@ class SparcV8TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
|
||||
: TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}
|
||||
|
||||
llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *Address) const override {
|
||||
int Offset;
|
||||
if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType()))
|
||||
Offset = 12;
|
||||
else
|
||||
Offset = 8;
|
||||
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
|
||||
llvm::ConstantInt::get(CGF.Int32Ty, Offset));
|
||||
}
|
||||
|
||||
llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *Address) const override {
|
||||
int Offset;
|
||||
if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType()))
|
||||
Offset = -12;
|
||||
else
|
||||
Offset = -8;
|
||||
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
|
||||
llvm::ConstantInt::get(CGF.Int32Ty, Offset));
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@ -9748,6 +9770,18 @@ class SparcV9TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
|
||||
bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *Address) const override;
|
||||
|
||||
llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *Address) const override {
|
||||
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
|
||||
llvm::ConstantInt::get(CGF.Int32Ty, 8));
|
||||
}
|
||||
|
||||
llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *Address) const override {
|
||||
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
|
||||
llvm::ConstantInt::get(CGF.Int32Ty, -8));
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
@ -1639,7 +1639,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
|
||||
const Driver &D = TC.getDriver();
|
||||
const llvm::Triple &Triple = TC.getEffectiveTriple();
|
||||
if (!(isAArch64 || (Triple.isArmT32() && Triple.isArmMClass())))
|
||||
D.Diag(diag::warn_target_unsupported_branch_protection_option)
|
||||
D.Diag(diag::warn_incompatible_branch_protection_option)
|
||||
<< Triple.getArchName();
|
||||
|
||||
StringRef Scope, Key;
|
||||
@ -8148,11 +8148,25 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
const InputInfoList &Inputs,
|
||||
const ArgList &Args,
|
||||
const char *LinkingOutput) const {
|
||||
const Driver &D = getToolChain().getDriver();
|
||||
const llvm::Triple TheTriple = getToolChain().getTriple();
|
||||
auto OpenMPTCRange = C.getOffloadToolChains<Action::OFK_OpenMP>();
|
||||
ArgStringList CmdArgs;
|
||||
|
||||
if (getToolChain().getDriver().isUsingLTO(/* IsOffload */ true)) {
|
||||
// Pass the CUDA path to the linker wrapper tool.
|
||||
for (auto &I : llvm::make_range(OpenMPTCRange.first, OpenMPTCRange.second)) {
|
||||
const ToolChain *TC = I.second;
|
||||
if (TC->getTriple().isNVPTX()) {
|
||||
CudaInstallationDetector CudaInstallation(D, TheTriple, Args);
|
||||
if (CudaInstallation.isValid())
|
||||
CmdArgs.push_back(Args.MakeArgString(
|
||||
"--cuda-path=" + CudaInstallation.getInstallPath()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (D.isUsingLTO(/* IsOffload */ true)) {
|
||||
// Pass in target features for each toolchain.
|
||||
auto OpenMPTCRange = C.getOffloadToolChains<Action::OFK_OpenMP>();
|
||||
for (auto &I :
|
||||
llvm::make_range(OpenMPTCRange.first, OpenMPTCRange.second)) {
|
||||
const ToolChain *TC = I.second;
|
||||
@ -8165,9 +8179,10 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
}
|
||||
|
||||
// Pass in the bitcode library to be linked during LTO.
|
||||
for (auto &I : llvm::make_range(OpenMPTCRange.first, OpenMPTCRange.second)) {
|
||||
for (auto &I :
|
||||
llvm::make_range(OpenMPTCRange.first, OpenMPTCRange.second)) {
|
||||
const ToolChain *TC = I.second;
|
||||
const Driver &D = TC->getDriver();
|
||||
const Driver &TCDriver = TC->getDriver();
|
||||
const ArgList &TCArgs = C.getArgsForToolChain(TC, "", Action::OFK_OpenMP);
|
||||
StringRef Arch = TCArgs.getLastArgValue(options::OPT_march_EQ);
|
||||
|
||||
@ -8182,7 +8197,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
BitcodeSuffix += Arch;
|
||||
|
||||
ArgStringList BitcodeLibrary;
|
||||
addOpenMPDeviceRTL(D, TCArgs, BitcodeLibrary, BitcodeSuffix,
|
||||
addOpenMPDeviceRTL(TCDriver, TCArgs, BitcodeLibrary, BitcodeSuffix,
|
||||
TC->getTriple());
|
||||
|
||||
if (!BitcodeLibrary.empty())
|
||||
@ -8210,12 +8225,8 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the link job so we can wrap around it.
|
||||
Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
|
||||
const auto &LinkCommand = C.getJobs().getJobs().back();
|
||||
|
||||
CmdArgs.push_back("-host-triple");
|
||||
CmdArgs.push_back(Args.MakeArgString(getToolChain().getTripleString()));
|
||||
CmdArgs.push_back(Args.MakeArgString(TheTriple.getTriple()));
|
||||
if (Args.hasArg(options::OPT_v))
|
||||
CmdArgs.push_back("-v");
|
||||
|
||||
@ -8246,6 +8257,10 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
if (Args.getLastArg(options::OPT_save_temps_EQ))
|
||||
CmdArgs.push_back("-save-temps");
|
||||
|
||||
// Construct the link job so we can wrap around it.
|
||||
Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
|
||||
const auto &LinkCommand = C.getJobs().getJobs().back();
|
||||
|
||||
// Add the linker arguments to be forwarded by the wrapper.
|
||||
CmdArgs.push_back("-linker-path");
|
||||
CmdArgs.push_back(LinkCommand->getExecutable());
|
||||
|
@ -72,23 +72,25 @@ static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args,
|
||||
(Cpu.back() == 'T' || Cpu.back() == 't' ? Cpu.drop_back(1) : Cpu).str();
|
||||
HasHVX = false;
|
||||
|
||||
// Handle -mhvx, -mhvx=, -mno-hvx. If both present, -mhvx= wins over -mhvx.
|
||||
auto argOrNull = [&Args](auto FlagOn, auto FlagOff) -> Arg* {
|
||||
if (Arg *A = Args.getLastArg(FlagOn, FlagOff)) {
|
||||
if (A->getOption().matches(FlagOn))
|
||||
return A;
|
||||
// Handle -mhvx, -mhvx=, -mno-hvx. If versioned and versionless flags
|
||||
// are both present, the last one wins.
|
||||
Arg *HvxEnablingArg =
|
||||
Args.getLastArg(options::OPT_mhexagon_hvx, options::OPT_mhexagon_hvx_EQ,
|
||||
options::OPT_mno_hexagon_hvx);
|
||||
if (HvxEnablingArg) {
|
||||
if (HvxEnablingArg->getOption().matches(options::OPT_mno_hexagon_hvx))
|
||||
HvxEnablingArg = nullptr;
|
||||
}
|
||||
|
||||
if (HvxEnablingArg) {
|
||||
// If -mhvx[=] was given, it takes precedence.
|
||||
if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx,
|
||||
options::OPT_mhexagon_hvx_EQ)) {
|
||||
// If the version was given, set HvxVer. Otherwise HvxVer
|
||||
// will remain equal to the CPU version.
|
||||
if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ))
|
||||
HvxVer = StringRef(A->getValue()).lower();
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
Arg *HvxBareA =
|
||||
argOrNull(options::OPT_mhexagon_hvx, options::OPT_mno_hexagon_hvx);
|
||||
Arg *HvxVerA =
|
||||
argOrNull(options::OPT_mhexagon_hvx_EQ, options::OPT_mno_hexagon_hvx);
|
||||
|
||||
if (Arg *A = HvxVerA ? HvxVerA : HvxBareA) {
|
||||
if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ))
|
||||
HvxVer = StringRef(A->getValue()).lower(); // lower produces std:string
|
||||
HasHVX = true;
|
||||
Features.push_back(makeFeature(Twine("hvx") + HvxVer, true));
|
||||
} else if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx)) {
|
||||
|
@ -1393,8 +1393,8 @@ VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
|
||||
if (MSVT.empty() &&
|
||||
Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
|
||||
IsWindowsMSVC)) {
|
||||
// -fms-compatibility-version=19.14 is default, aka 2017, 15.7
|
||||
MSVT = VersionTuple(19, 14);
|
||||
// -fms-compatibility-version=19.20 is default, aka 2019, 16.x
|
||||
MSVT = VersionTuple(19, 20);
|
||||
}
|
||||
return MSVT;
|
||||
}
|
||||
|
@ -86,7 +86,9 @@ void tools::MinGW::Linker::AddLibGCC(const ArgList &Args,
|
||||
CmdArgs.push_back("-lmoldname");
|
||||
CmdArgs.push_back("-lmingwex");
|
||||
for (auto Lib : Args.getAllArgValues(options::OPT_l))
|
||||
if (StringRef(Lib).startswith("msvcr") || StringRef(Lib).startswith("ucrt"))
|
||||
if (StringRef(Lib).startswith("msvcr") ||
|
||||
StringRef(Lib).startswith("ucrt") ||
|
||||
StringRef(Lib).startswith("crtdll"))
|
||||
return;
|
||||
CmdArgs.push_back("-lmsvcrt");
|
||||
}
|
||||
|
@ -90,6 +90,8 @@ class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain {
|
||||
|
||||
void printVerboseInfo(raw_ostream &OS) const override;
|
||||
|
||||
unsigned GetDefaultDwarfVersion() const override { return 4; }
|
||||
|
||||
protected:
|
||||
Tool *getTool(Action::ActionClass AC) const override;
|
||||
Tool *buildLinker() const override;
|
||||
|
@ -160,7 +160,8 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
assert(Output.isNothing() && "Invalid output.");
|
||||
}
|
||||
|
||||
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
|
||||
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
|
||||
options::OPT_r)) {
|
||||
const char *crt0 = nullptr;
|
||||
const char *crtbegin = nullptr;
|
||||
if (!Args.hasArg(options::OPT_shared)) {
|
||||
@ -191,7 +192,8 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
|
||||
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
|
||||
|
||||
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
|
||||
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
|
||||
options::OPT_r)) {
|
||||
// Use the static OpenMP runtime with -static-openmp
|
||||
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
|
||||
!Args.hasArg(options::OPT_static);
|
||||
@ -234,7 +236,8 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
CmdArgs.push_back("-lcompiler_rt");
|
||||
}
|
||||
|
||||
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
|
||||
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
|
||||
options::OPT_r)) {
|
||||
const char *crtend = nullptr;
|
||||
if (!Args.hasArg(options::OPT_shared))
|
||||
crtend = "crtend.o";
|
||||
|
@ -35,19 +35,31 @@ void DefinitionBlockSeparator::separateBlocks(
|
||||
const bool IsNeverStyle =
|
||||
Style.SeparateDefinitionBlocks == FormatStyle::SDS_Never;
|
||||
const AdditionalKeywords &ExtraKeywords = Tokens.getKeywords();
|
||||
auto LikelyDefinition = [this, ExtraKeywords](const AnnotatedLine *Line,
|
||||
bool ExcludeEnum = false) {
|
||||
auto GetBracketLevelChange = [](const FormatToken *Tok) {
|
||||
if (Tok->isOneOf(tok::l_brace, tok::l_paren, tok::l_square))
|
||||
return 1;
|
||||
if (Tok->isOneOf(tok::r_brace, tok::r_paren, tok::r_square))
|
||||
return -1;
|
||||
return 0;
|
||||
};
|
||||
auto LikelyDefinition = [&](const AnnotatedLine *Line,
|
||||
bool ExcludeEnum = false) {
|
||||
if ((Line->MightBeFunctionDecl && Line->mightBeFunctionDefinition()) ||
|
||||
Line->startsWithNamespace())
|
||||
return true;
|
||||
FormatToken *CurrentToken = Line->First;
|
||||
while (CurrentToken) {
|
||||
if (CurrentToken->isOneOf(tok::kw_class, tok::kw_struct) ||
|
||||
(Style.isJavaScript() && CurrentToken->is(ExtraKeywords.kw_function)))
|
||||
return true;
|
||||
if (!ExcludeEnum && CurrentToken->is(tok::kw_enum))
|
||||
return true;
|
||||
CurrentToken = CurrentToken->Next;
|
||||
int BracketLevel = 0;
|
||||
for (const FormatToken *CurrentToken = Line->First; CurrentToken;
|
||||
CurrentToken = CurrentToken->Next) {
|
||||
if (BracketLevel == 0) {
|
||||
if ((CurrentToken->isOneOf(tok::kw_class, tok::kw_struct,
|
||||
tok::kw_union) ||
|
||||
(Style.isJavaScript() &&
|
||||
CurrentToken->is(ExtraKeywords.kw_function))))
|
||||
return true;
|
||||
if (!ExcludeEnum && CurrentToken->is(tok::kw_enum))
|
||||
return true;
|
||||
}
|
||||
BracketLevel += GetBracketLevelChange(CurrentToken);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@ -102,14 +114,17 @@ void DefinitionBlockSeparator::separateBlocks(
|
||||
IsPPConditional(OpeningLineIndex - 1);
|
||||
};
|
||||
const auto HasEnumOnLine = [&]() {
|
||||
FormatToken *CurrentToken = CurrentLine->First;
|
||||
bool FoundEnumKeyword = false;
|
||||
while (CurrentToken) {
|
||||
if (CurrentToken->is(tok::kw_enum))
|
||||
FoundEnumKeyword = true;
|
||||
else if (FoundEnumKeyword && CurrentToken->is(tok::l_brace))
|
||||
return true;
|
||||
CurrentToken = CurrentToken->Next;
|
||||
int BracketLevel = 0;
|
||||
for (const FormatToken *CurrentToken = CurrentLine->First; CurrentToken;
|
||||
CurrentToken = CurrentToken->Next) {
|
||||
if (BracketLevel == 0) {
|
||||
if (CurrentToken->is(tok::kw_enum))
|
||||
FoundEnumKeyword = true;
|
||||
else if (FoundEnumKeyword && CurrentToken->is(tok::l_brace))
|
||||
return true;
|
||||
}
|
||||
BracketLevel += GetBracketLevelChange(CurrentToken);
|
||||
}
|
||||
return FoundEnumKeyword && I + 1 < Lines.size() &&
|
||||
Lines[I + 1]->First->is(tok::l_brace);
|
||||
|
@ -396,6 +396,10 @@ LeftRightQualifierAlignmentFixer::analyze(
|
||||
|
||||
for (AnnotatedLine *Line : AnnotatedLines) {
|
||||
FormatToken *First = Line->First;
|
||||
assert(First);
|
||||
if (First->Finalized)
|
||||
continue;
|
||||
|
||||
const auto *Last = Line->Last;
|
||||
|
||||
for (const auto *Tok = First; Tok && Tok != Last && Tok->Next;
|
||||
|
@ -3102,7 +3102,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
|
||||
}
|
||||
if (FormatTok->is(tok::l_square)) {
|
||||
FormatToken *Previous = FormatTok->Previous;
|
||||
if (!Previous || Previous->isNot(tok::r_paren)) {
|
||||
if (!Previous ||
|
||||
!(Previous->is(tok::r_paren) || Previous->isTypeOrIdentifier())) {
|
||||
// Don't try parsing a lambda if we had a closing parenthesis before,
|
||||
// it was probably a pointer to an array: int (*)[].
|
||||
if (!tryToParseLambda())
|
||||
|
@ -67,6 +67,8 @@
|
||||
#if (__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300)
|
||||
// For the SPIR and SPIR-V target all features are supported.
|
||||
#if defined(__SPIR__) || defined(__SPIRV__)
|
||||
#define __opencl_c_atomic_order_seq_cst 1
|
||||
#define __opencl_c_atomic_scope_device 1
|
||||
#define __opencl_c_atomic_scope_all_devices 1
|
||||
#define __opencl_c_read_write_images 1
|
||||
#endif // defined(__SPIR__)
|
||||
|
@ -13832,6 +13832,7 @@ float __ovld atomic_fetch_max_explicit(volatile atomic_float *object,
|
||||
#endif // defined(__opencl_c_ext_fp32_global_atomic_min_max) && \
|
||||
defined(__opencl_c_ext_fp32_local_atomic_min_max)
|
||||
|
||||
#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics)
|
||||
#if defined(__opencl_c_ext_fp64_global_atomic_min_max)
|
||||
double __ovld atomic_fetch_min(volatile __global atomic_double *object,
|
||||
double operand);
|
||||
@ -13882,6 +13883,8 @@ double __ovld atomic_fetch_max_explicit(volatile atomic_double *object,
|
||||
memory_scope scope);
|
||||
#endif // defined(__opencl_c_ext_fp64_global_atomic_min_max) && \
|
||||
defined(__opencl_c_ext_fp64_local_atomic_min_max)
|
||||
#endif // defined(cl_khr_int64_base_atomics) && \
|
||||
defined(cl_khr_int64_extended_atomics)
|
||||
|
||||
#if defined(__opencl_c_ext_fp16_global_atomic_add)
|
||||
half __ovld atomic_fetch_add(volatile __global atomic_half *object,
|
||||
@ -13985,6 +13988,7 @@ float __ovld atomic_fetch_sub_explicit(volatile atomic_float *object,
|
||||
#endif // defined(__opencl_c_ext_fp32_global_atomic_add) && \
|
||||
defined(__opencl_c_ext_fp32_local_atomic_add)
|
||||
|
||||
#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics)
|
||||
#if defined(__opencl_c_ext_fp64_global_atomic_add)
|
||||
double __ovld atomic_fetch_add(volatile __global atomic_double *object,
|
||||
double operand);
|
||||
@ -14035,6 +14039,8 @@ double __ovld atomic_fetch_sub_explicit(volatile atomic_double *object,
|
||||
memory_scope scope);
|
||||
#endif // defined(__opencl_c_ext_fp64_global_atomic_add) && \
|
||||
defined(__opencl_c_ext_fp64_local_atomic_add)
|
||||
#endif // defined(cl_khr_int64_base_atomics) && \
|
||||
defined(cl_khr_int64_extended_atomics)
|
||||
|
||||
#endif // cl_ext_float_atomics
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef __cplusplus
|
||||
extern int posix_memalign (void **, size_t, size_t);
|
||||
#else
|
||||
extern "C" int posix_memalign (void **, size_t, size_t) throw ();
|
||||
extern "C" int posix_memalign (void **, size_t, size_t);
|
||||
#endif
|
||||
|
||||
static __inline void *
|
||||
|
@ -57,6 +57,23 @@ class FunctionExtension<string _Ext> : AbstractExtension<_Ext>;
|
||||
// disabled.
|
||||
class TypeExtension<string _Ext> : AbstractExtension<_Ext>;
|
||||
|
||||
// Concatenate zero or more space-separated extensions in NewExts to Base and
|
||||
// return the resulting FunctionExtension in ret.
|
||||
class concatExtension<FunctionExtension Base, string NewExts> {
|
||||
FunctionExtension ret = FunctionExtension<
|
||||
!cond(
|
||||
// Return Base extension if NewExts is empty,
|
||||
!empty(NewExts) : Base.ExtName,
|
||||
|
||||
// otherwise, return NewExts if Base extension is empty,
|
||||
!empty(Base.ExtName) : NewExts,
|
||||
|
||||
// otherwise, concatenate NewExts to Base.
|
||||
true : Base.ExtName # " " # NewExts
|
||||
)
|
||||
>;
|
||||
}
|
||||
|
||||
// TypeExtension definitions.
|
||||
def NoTypeExt : TypeExtension<"">;
|
||||
def Fp16TypeExt : TypeExtension<"cl_khr_fp16">;
|
||||
@ -90,27 +107,27 @@ def FuncExtOpenCLCNamedAddressSpaceBuiltins : FunctionExtension<"__opencl_c_name
|
||||
def FuncExtOpenCLCPipes : FunctionExtension<"__opencl_c_pipes">;
|
||||
def FuncExtOpenCLCWGCollectiveFunctions : FunctionExtension<"__opencl_c_work_group_collective_functions">;
|
||||
def FuncExtOpenCLCReadWriteImages : FunctionExtension<"__opencl_c_read_write_images">;
|
||||
def FuncExtFloatAtomicsFp16GlobalLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_load_store">;
|
||||
def FuncExtFloatAtomicsFp16LocalLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_load_store">;
|
||||
def FuncExtFloatAtomicsFp16GenericLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_load_store __opencl_c_ext_fp16_local_atomic_load_store">;
|
||||
def FuncExtFloatAtomicsFp16GlobalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp32GlobalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp64GlobalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp16LocalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp32LocalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp64LocalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp16GenericAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_add __opencl_c_ext_fp16_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp32GenericAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_add __opencl_c_ext_fp32_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp64GenericAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_add __opencl_c_ext_fp64_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp16GlobalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp32GlobalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp64GlobalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp16LocalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp32LocalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp64LocalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp16GenericMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_min_max __opencl_c_ext_fp16_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp32GenericMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_min_max __opencl_c_ext_fp32_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp64GenericMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_min_max __opencl_c_ext_fp64_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp16GlobalASLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_load_store">;
|
||||
def FuncExtFloatAtomicsFp16LocalASLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_load_store">;
|
||||
def FuncExtFloatAtomicsFp16GenericASLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_load_store __opencl_c_ext_fp16_local_atomic_load_store">;
|
||||
def FuncExtFloatAtomicsFp16GlobalASAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp32GlobalASAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp64GlobalASAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp16LocalASAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp32LocalASAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp64LocalASAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp16GenericASAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_add __opencl_c_ext_fp16_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp32GenericASAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_add __opencl_c_ext_fp32_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp64GenericASAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_add __opencl_c_ext_fp64_global_atomic_add">;
|
||||
def FuncExtFloatAtomicsFp16GlobalASMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp32GlobalASMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp64GlobalASMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp16LocalASMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp32LocalASMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp64LocalASMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp16GenericASMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_min_max __opencl_c_ext_fp16_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp32GenericASMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_min_max __opencl_c_ext_fp32_global_atomic_min_max">;
|
||||
def FuncExtFloatAtomicsFp64GenericASMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_min_max __opencl_c_ext_fp64_global_atomic_min_max">;
|
||||
|
||||
// Not a real extension, but a workaround to add C++ for OpenCL specific builtins.
|
||||
def FuncExtOpenCLCxx : FunctionExtension<"__cplusplus">;
|
||||
@ -1041,42 +1058,59 @@ let Extension = FuncExtOpenCLCxx in {
|
||||
}
|
||||
|
||||
// OpenCL v2.0 s6.13.11 - Atomic Functions.
|
||||
let MinVersion = CL20 in {
|
||||
def : Builtin<"atomic_work_item_fence", [Void, MemFenceFlags, MemoryOrder, MemoryScope]>;
|
||||
|
||||
// An atomic builtin with 2 additional _explicit variants.
|
||||
multiclass BuiltinAtomicExplicit<string Name, list<Type> Types, FunctionExtension BaseExt> {
|
||||
// Without explicit MemoryOrder or MemoryScope.
|
||||
let Extension = concatExtension<BaseExt, "__opencl_c_atomic_order_seq_cst __opencl_c_atomic_scope_device">.ret in {
|
||||
def : Builtin<Name, Types>;
|
||||
}
|
||||
|
||||
// With an explicit MemoryOrder argument.
|
||||
let Extension = concatExtension<BaseExt, "__opencl_c_atomic_scope_device">.ret in {
|
||||
def : Builtin<Name # "_explicit", !listconcat(Types, [MemoryOrder])>;
|
||||
}
|
||||
|
||||
// With explicit MemoryOrder and MemoryScope arguments.
|
||||
let Extension = BaseExt in {
|
||||
def : Builtin<Name # "_explicit", !listconcat(Types, [MemoryOrder, MemoryScope])>;
|
||||
}
|
||||
}
|
||||
|
||||
// OpenCL 2.0 atomic functions that have a pointer argument in a given address space.
|
||||
multiclass OpenCL2Atomics<AddressSpace addrspace, FunctionExtension BaseExt> {
|
||||
foreach TypePair = [[AtomicInt, Int], [AtomicUInt, UInt],
|
||||
[AtomicLong, Long], [AtomicULong, ULong],
|
||||
[AtomicFloat, Float], [AtomicDouble, Double]] in {
|
||||
def : Builtin<"atomic_init",
|
||||
[Void, PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1]]>;
|
||||
def : Builtin<"atomic_store",
|
||||
[Void, PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1]]>;
|
||||
def : Builtin<"atomic_store_explicit",
|
||||
[Void, PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1], MemoryOrder]>;
|
||||
def : Builtin<"atomic_store_explicit",
|
||||
[Void, PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1], MemoryOrder, MemoryScope]>;
|
||||
def : Builtin<"atomic_load",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>]>;
|
||||
def : Builtin<"atomic_load_explicit",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, MemoryOrder]>;
|
||||
def : Builtin<"atomic_load_explicit",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, MemoryOrder, MemoryScope]>;
|
||||
def : Builtin<"atomic_exchange",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1]]>;
|
||||
def : Builtin<"atomic_exchange_explicit",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1], MemoryOrder]>;
|
||||
def : Builtin<"atomic_exchange_explicit",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1], MemoryOrder, MemoryScope]>;
|
||||
[Void, PointerType<VolatileType<TypePair[0]>, addrspace>, TypePair[1]]>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_store",
|
||||
[Void, PointerType<VolatileType<TypePair[0]>, addrspace>, TypePair[1]], BaseExt>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_load",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, addrspace>], BaseExt>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_exchange",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, addrspace>, TypePair[1]], BaseExt>;
|
||||
foreach Variant = ["weak", "strong"] in {
|
||||
def : Builtin<"atomic_compare_exchange_" # Variant,
|
||||
[Bool, PointerType<VolatileType<TypePair[0]>, GenericAS>,
|
||||
PointerType<TypePair[1], GenericAS>, TypePair[1]]>;
|
||||
def : Builtin<"atomic_compare_exchange_" # Variant # "_explicit",
|
||||
[Bool, PointerType<VolatileType<TypePair[0]>, GenericAS>,
|
||||
PointerType<TypePair[1], GenericAS>, TypePair[1], MemoryOrder, MemoryOrder]>;
|
||||
def : Builtin<"atomic_compare_exchange_" # Variant # "_explicit",
|
||||
[Bool, PointerType<VolatileType<TypePair[0]>, GenericAS>,
|
||||
PointerType<TypePair[1], GenericAS>, TypePair[1], MemoryOrder, MemoryOrder, MemoryScope]>;
|
||||
foreach exp_ptr_addrspace = !cond(
|
||||
!eq(BaseExt, FuncExtOpenCLCGenericAddressSpace): [GenericAS],
|
||||
!eq(BaseExt, FuncExtOpenCLCNamedAddressSpaceBuiltins): [GlobalAS, LocalAS, PrivateAS])
|
||||
in {
|
||||
let Extension = concatExtension<BaseExt, "__opencl_c_atomic_order_seq_cst __opencl_c_atomic_scope_device">.ret in {
|
||||
def : Builtin<"atomic_compare_exchange_" # Variant,
|
||||
[Bool, PointerType<VolatileType<TypePair[0]>, addrspace>,
|
||||
PointerType<TypePair[1], exp_ptr_addrspace>, TypePair[1]]>;
|
||||
}
|
||||
let Extension = concatExtension<BaseExt, "__opencl_c_atomic_scope_device">.ret in {
|
||||
def : Builtin<"atomic_compare_exchange_" # Variant # "_explicit",
|
||||
[Bool, PointerType<VolatileType<TypePair[0]>, addrspace>,
|
||||
PointerType<TypePair[1], exp_ptr_addrspace>, TypePair[1], MemoryOrder, MemoryOrder]>;
|
||||
}
|
||||
let Extension = BaseExt in {
|
||||
def : Builtin<"atomic_compare_exchange_" # Variant # "_explicit",
|
||||
[Bool, PointerType<VolatileType<TypePair[0]>, addrspace>,
|
||||
PointerType<TypePair[1], exp_ptr_addrspace>, TypePair[1], MemoryOrder, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1084,249 +1118,69 @@ let MinVersion = CL20 in {
|
||||
[AtomicLong, Long, Long], [AtomicULong, ULong, ULong],
|
||||
[AtomicUIntPtr, UIntPtr, PtrDiff]] in {
|
||||
foreach ModOp = ["add", "sub"] in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2]]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2], MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2], MemoryOrder, MemoryScope]>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_fetch_" # ModOp,
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, addrspace>, TypePair[2]], BaseExt>;
|
||||
}
|
||||
}
|
||||
foreach TypePair = [[AtomicInt, Int, Int], [AtomicUInt, UInt, UInt],
|
||||
[AtomicLong, Long, Long], [AtomicULong, ULong, ULong]] in {
|
||||
foreach ModOp = ["or", "xor", "and", "min", "max"] in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2]]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2], MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2], MemoryOrder, MemoryScope]>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_fetch_" # ModOp,
|
||||
[TypePair[1], PointerType<VolatileType<TypePair[0]>, addrspace>, TypePair[2]], BaseExt>;
|
||||
}
|
||||
}
|
||||
|
||||
def : Builtin<"atomic_flag_clear",
|
||||
[Void, PointerType<VolatileType<AtomicFlag>, GenericAS>]>;
|
||||
def : Builtin<"atomic_flag_clear_explicit",
|
||||
[Void, PointerType<VolatileType<AtomicFlag>, GenericAS>, MemoryOrder]>;
|
||||
def : Builtin<"atomic_flag_clear_explicit",
|
||||
[Void, PointerType<VolatileType<AtomicFlag>, GenericAS>, MemoryOrder, MemoryScope]>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_flag_clear",
|
||||
[Void, PointerType<VolatileType<AtomicFlag>, addrspace>], BaseExt>;
|
||||
|
||||
def : Builtin<"atomic_flag_test_and_set",
|
||||
[Bool, PointerType<VolatileType<AtomicFlag>, GenericAS>]>;
|
||||
def : Builtin<"atomic_flag_test_and_set_explicit",
|
||||
[Bool, PointerType<VolatileType<AtomicFlag>, GenericAS>, MemoryOrder]>;
|
||||
def : Builtin<"atomic_flag_test_and_set_explicit",
|
||||
[Bool, PointerType<VolatileType<AtomicFlag>, GenericAS>, MemoryOrder, MemoryScope]>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_flag_test_and_set",
|
||||
[Bool, PointerType<VolatileType<AtomicFlag>, addrspace>], BaseExt>;
|
||||
}
|
||||
|
||||
let MinVersion = CL20 in {
|
||||
def : Builtin<"atomic_work_item_fence", [Void, MemFenceFlags, MemoryOrder, MemoryScope]>;
|
||||
|
||||
defm : OpenCL2Atomics<GenericAS, FuncExtOpenCLCGenericAddressSpace>;
|
||||
defm : OpenCL2Atomics<GlobalAS, FuncExtOpenCLCNamedAddressSpaceBuiltins>;
|
||||
defm : OpenCL2Atomics<LocalAS, FuncExtOpenCLCNamedAddressSpaceBuiltins>;
|
||||
}
|
||||
|
||||
// The functionality added by cl_ext_float_atomics extension
|
||||
let MinVersion = CL20 in {
|
||||
let Extension = FuncExtFloatAtomicsFp16GlobalLoadStore in {
|
||||
def : Builtin<"atomic_store",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, GlobalAS>, AtomicHalf]>;
|
||||
def : Builtin<"atomic_store_explicit",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, GlobalAS>, AtomicHalf, MemoryOrder]>;
|
||||
def : Builtin<"atomic_store_explicit",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, GlobalAS>, AtomicHalf, MemoryOrder, MemoryScope]>;
|
||||
def : Builtin<"atomic_load",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>]>;
|
||||
def : Builtin<"atomic_load_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, MemoryOrder]>;
|
||||
def : Builtin<"atomic_load_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, MemoryOrder, MemoryScope]>;
|
||||
def : Builtin<"atomic_exchange",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half]>;
|
||||
def : Builtin<"atomic_exchange_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half, MemoryOrder]>;
|
||||
def : Builtin<"atomic_exchange_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp16LocalLoadStore in {
|
||||
def : Builtin<"atomic_store",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, LocalAS>, AtomicHalf]>;
|
||||
def : Builtin<"atomic_store_explicit",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, LocalAS>, AtomicHalf, MemoryOrder]>;
|
||||
def : Builtin<"atomic_store_explicit",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, LocalAS>, AtomicHalf, MemoryOrder, MemoryScope]>;
|
||||
def : Builtin<"atomic_load",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, LocalAS>]>;
|
||||
def : Builtin<"atomic_load_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, MemoryOrder]>;
|
||||
def : Builtin<"atomic_load_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, MemoryOrder, MemoryScope]>;
|
||||
def : Builtin<"atomic_exchange",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half]>;
|
||||
def : Builtin<"atomic_exchange_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half, MemoryOrder]>;
|
||||
def : Builtin<"atomic_exchange_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp16GenericLoadStore in {
|
||||
def : Builtin<"atomic_store",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, GenericAS>, AtomicHalf]>;
|
||||
def : Builtin<"atomic_store_explicit",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, GenericAS>, AtomicHalf, MemoryOrder]>;
|
||||
def : Builtin<"atomic_store_explicit",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, GenericAS>, AtomicHalf, MemoryOrder, MemoryScope]>;
|
||||
def : Builtin<"atomic_load",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GenericAS>]>;
|
||||
def : Builtin<"atomic_load_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, MemoryOrder]>;
|
||||
def : Builtin<"atomic_load_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, MemoryOrder, MemoryScope]>;
|
||||
def : Builtin<"atomic_exchange",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half]>;
|
||||
def : Builtin<"atomic_exchange_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half, MemoryOrder]>;
|
||||
def : Builtin<"atomic_exchange_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
foreach ModOp = ["add", "sub"] in {
|
||||
let Extension = FuncExtFloatAtomicsFp16GlobalAdd in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Half]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Half, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Half, MemoryOrder, MemoryScope]>;
|
||||
foreach addrspace = [GlobalAS, LocalAS, GenericAS] in {
|
||||
defvar extension_fp16 = !cast<FunctionExtension>("FuncExtFloatAtomicsFp16" # addrspace # "LoadStore");
|
||||
|
||||
defm : BuiltinAtomicExplicit<"atomic_store",
|
||||
[Void, PointerType<VolatileType<AtomicHalf>, addrspace>, AtomicHalf], extension_fp16>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_load",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, addrspace>], extension_fp16>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_exchange",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, addrspace>, Half], extension_fp16>;
|
||||
|
||||
foreach ModOp = ["add", "sub"] in {
|
||||
defvar extension_fp16 = !cast<FunctionExtension>("FuncExtFloatAtomicsFp16" # addrspace # "Add");
|
||||
defvar extension_fp32 = !cast<FunctionExtension>("FuncExtFloatAtomicsFp32" # addrspace # "Add");
|
||||
defvar extension_fp64 = !cast<FunctionExtension>("FuncExtFloatAtomicsFp64" # addrspace # "Add");
|
||||
|
||||
defm : BuiltinAtomicExplicit<"atomic_fetch_" # ModOp,
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, addrspace>, Half], extension_fp16>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_fetch_" # ModOp,
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, addrspace>, Float], extension_fp32>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_fetch_" # ModOp,
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, addrspace>, Double], extension_fp64>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp32GlobalAdd in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp64GlobalAdd in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp16LocalAdd in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, LocalAS>, Half]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, LocalAS>, Half, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, LocalAS>, Half, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp32LocalAdd in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp64LocalAdd in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp16GenericAdd in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, GenericAS>, Half]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, GenericAS>, Half, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicFloat>, GenericAS>, Half, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp32GenericAdd in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp64GenericAdd in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
}
|
||||
foreach ModOp = ["min", "max"] in {
|
||||
let Extension = FuncExtFloatAtomicsFp16GlobalMinMax in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp32GlobalMinMax in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp64GlobalMinMax in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp16LocalMinMax in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp32LocalMinMax in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp64LocalMinMax in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp16GenericMinMax in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp32GenericMinMax in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder, MemoryScope]>;
|
||||
}
|
||||
let Extension = FuncExtFloatAtomicsFp64GenericMinMax in {
|
||||
def : Builtin<"atomic_fetch_" # ModOp,
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder]>;
|
||||
def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder, MemoryScope]>;
|
||||
|
||||
foreach ModOp = ["min", "max"] in {
|
||||
defvar extension_fp16 = !cast<FunctionExtension>("FuncExtFloatAtomicsFp16" # addrspace # "MinMax");
|
||||
defvar extension_fp32 = !cast<FunctionExtension>("FuncExtFloatAtomicsFp32" # addrspace # "MinMax");
|
||||
defvar extension_fp64 = !cast<FunctionExtension>("FuncExtFloatAtomicsFp64" # addrspace # "MinMax");
|
||||
|
||||
defm : BuiltinAtomicExplicit<"atomic_fetch_" # ModOp,
|
||||
[Half, PointerType<VolatileType<AtomicHalf>, addrspace>, Half], extension_fp16>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_fetch_" # ModOp,
|
||||
[Float, PointerType<VolatileType<AtomicFloat>, addrspace>, Float], extension_fp32>;
|
||||
defm : BuiltinAtomicExplicit<"atomic_fetch_" # ModOp,
|
||||
[Double, PointerType<VolatileType<AtomicDouble>, addrspace>, Double], extension_fp64>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1042,9 +1042,15 @@ static bool checkOpenCLBlockArgs(Sema &S, Expr *BlockArg) {
|
||||
}
|
||||
|
||||
static bool checkOpenCLSubgroupExt(Sema &S, CallExpr *Call) {
|
||||
if (!S.getOpenCLOptions().isSupported("cl_khr_subgroups", S.getLangOpts())) {
|
||||
// OpenCL device can support extension but not the feature as extension
|
||||
// requires subgroup independent forward progress, but subgroup independent
|
||||
// forward progress is optional in OpenCL C 3.0 __opencl_c_subgroups feature.
|
||||
if (!S.getOpenCLOptions().isSupported("cl_khr_subgroups", S.getLangOpts()) &&
|
||||
!S.getOpenCLOptions().isSupported("__opencl_c_subgroups",
|
||||
S.getLangOpts())) {
|
||||
S.Diag(Call->getBeginLoc(), diag::err_opencl_requires_extension)
|
||||
<< 1 << Call->getDirectCallee() << "cl_khr_subgroups";
|
||||
<< 1 << Call->getDirectCallee()
|
||||
<< "cl_khr_subgroups or __opencl_c_subgroups";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -15319,24 +15319,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
|
||||
if (!FD->hasAttr<AllocAlignAttr>())
|
||||
FD->addAttr(AllocAlignAttr::CreateImplicit(Context, ParamIdx(1, FD),
|
||||
FD->getLocation()));
|
||||
LLVM_FALLTHROUGH;
|
||||
case Builtin::BIcalloc:
|
||||
case Builtin::BImalloc:
|
||||
case Builtin::BImemalign:
|
||||
case Builtin::BIrealloc:
|
||||
case Builtin::BIstrdup:
|
||||
case Builtin::BIstrndup: {
|
||||
if (!FD->hasAttr<AssumeAlignedAttr>()) {
|
||||
unsigned NewAlign = Context.getTargetInfo().getNewAlign() /
|
||||
Context.getTargetInfo().getCharWidth();
|
||||
IntegerLiteral *Alignment = IntegerLiteral::Create(
|
||||
Context, Context.MakeIntValue(NewAlign, Context.UnsignedIntTy),
|
||||
Context.UnsignedIntTy, FD->getLocation());
|
||||
FD->addAttr(AssumeAlignedAttr::CreateImplicit(
|
||||
Context, Alignment, /*Offset=*/nullptr, FD->getLocation()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -53,9 +53,9 @@ struct ErrorDeadlySignal : ErrorBase {
|
||||
scariness.Scare(10, "null-deref");
|
||||
} else if (signal.addr == signal.pc) {
|
||||
scariness.Scare(60, "wild-jump");
|
||||
} else if (signal.write_flag == SignalContext::WRITE) {
|
||||
} else if (signal.write_flag == SignalContext::Write) {
|
||||
scariness.Scare(30, "wild-addr-write");
|
||||
} else if (signal.write_flag == SignalContext::READ) {
|
||||
} else if (signal.write_flag == SignalContext::Read) {
|
||||
scariness.Scare(20, "wild-addr-read");
|
||||
} else {
|
||||
scariness.Scare(25, "wild-addr");
|
||||
|
@ -956,7 +956,7 @@ struct SignalContext {
|
||||
uptr sp;
|
||||
uptr bp;
|
||||
bool is_memory_access;
|
||||
enum WriteFlag { UNKNOWN, READ, WRITE } write_flag;
|
||||
enum WriteFlag { Unknown, Read, Write } write_flag;
|
||||
|
||||
// In some cases the kernel cannot provide the true faulting address; `addr`
|
||||
// will be zero then. This field allows to distinguish between these cases
|
||||
|
@ -1825,7 +1825,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
#else
|
||||
uptr err = ucontext->uc_mcontext.gregs[REG_ERR];
|
||||
#endif // SANITIZER_FREEBSD
|
||||
return err & PF_WRITE ? WRITE : READ;
|
||||
return err & PF_WRITE ? Write : Read;
|
||||
#elif defined(__mips__)
|
||||
uint32_t *exception_source;
|
||||
uint32_t faulty_instruction;
|
||||
@ -1848,7 +1848,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
case 0x2a: // swl
|
||||
case 0x2e: // swr
|
||||
#endif
|
||||
return SignalContext::WRITE;
|
||||
return SignalContext::Write;
|
||||
|
||||
case 0x20: // lb
|
||||
case 0x24: // lbu
|
||||
@ -1863,27 +1863,27 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
case 0x22: // lwl
|
||||
case 0x26: // lwr
|
||||
#endif
|
||||
return SignalContext::READ;
|
||||
return SignalContext::Read;
|
||||
#if __mips_isa_rev == 6
|
||||
case 0x3b: // pcrel
|
||||
op_code = (faulty_instruction >> 19) & 0x3;
|
||||
switch (op_code) {
|
||||
case 0x1: // lwpc
|
||||
case 0x2: // lwupc
|
||||
return SignalContext::READ;
|
||||
return SignalContext::Read;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
#elif defined(__arm__)
|
||||
static const uptr FSR_WRITE = 1U << 11;
|
||||
uptr fsr = ucontext->uc_mcontext.error_code;
|
||||
return fsr & FSR_WRITE ? WRITE : READ;
|
||||
return fsr & FSR_WRITE ? Write : Read;
|
||||
#elif defined(__aarch64__)
|
||||
static const u64 ESR_ELx_WNR = 1U << 6;
|
||||
u64 esr;
|
||||
if (!Aarch64GetESR(ucontext, &esr)) return UNKNOWN;
|
||||
return esr & ESR_ELx_WNR ? WRITE : READ;
|
||||
if (!Aarch64GetESR(ucontext, &esr)) return Unknown;
|
||||
return esr & ESR_ELx_WNR ? Write : Read;
|
||||
#elif defined(__sparc__)
|
||||
// Decode the instruction to determine the access type.
|
||||
// From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype).
|
||||
@ -1899,7 +1899,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
#endif
|
||||
#endif
|
||||
u32 instr = *(u32 *)pc;
|
||||
return (instr >> 21) & 1 ? WRITE: READ;
|
||||
return (instr >> 21) & 1 ? Write: Read;
|
||||
#elif defined(__riscv)
|
||||
#if SANITIZER_FREEBSD
|
||||
unsigned long pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc;
|
||||
@ -1919,7 +1919,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
#if __riscv_xlen == 64
|
||||
case 0b10'011: // c.ldsp (rd != x0)
|
||||
#endif
|
||||
return rd ? SignalContext::READ : SignalContext::UNKNOWN;
|
||||
return rd ? SignalContext::Read : SignalContext::Unknown;
|
||||
case 0b00'010: // c.lw
|
||||
#if __riscv_flen >= 32 && __riscv_xlen == 32
|
||||
case 0b10'011: // c.flwsp
|
||||
@ -1931,7 +1931,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
case 0b00'001: // c.fld
|
||||
case 0b10'001: // c.fldsp
|
||||
#endif
|
||||
return SignalContext::READ;
|
||||
return SignalContext::Read;
|
||||
case 0b00'110: // c.sw
|
||||
case 0b10'110: // c.swsp
|
||||
#if __riscv_flen >= 32 || __riscv_xlen == 64
|
||||
@ -1942,9 +1942,9 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
case 0b00'101: // c.fsd
|
||||
case 0b10'101: // c.fsdsp
|
||||
#endif
|
||||
return SignalContext::WRITE;
|
||||
return SignalContext::Write;
|
||||
default:
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1962,9 +1962,9 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
#endif
|
||||
case 0b100: // lbu
|
||||
case 0b101: // lhu
|
||||
return SignalContext::READ;
|
||||
return SignalContext::Read;
|
||||
default:
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
}
|
||||
case 0b0100011: // stores
|
||||
switch (funct3) {
|
||||
@ -1974,9 +1974,9 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
#if __riscv_xlen == 64
|
||||
case 0b011: // sd
|
||||
#endif
|
||||
return SignalContext::WRITE;
|
||||
return SignalContext::Write;
|
||||
default:
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
}
|
||||
#if __riscv_flen >= 32
|
||||
case 0b0000111: // floating-point loads
|
||||
@ -1985,9 +1985,9 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
#if __riscv_flen == 64
|
||||
case 0b011: // fld
|
||||
#endif
|
||||
return SignalContext::READ;
|
||||
return SignalContext::Read;
|
||||
default:
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
}
|
||||
case 0b0100111: // floating-point stores
|
||||
switch (funct3) {
|
||||
@ -1995,17 +1995,17 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
#if __riscv_flen == 64
|
||||
case 0b011: // fsd
|
||||
#endif
|
||||
return SignalContext::WRITE;
|
||||
return SignalContext::Write;
|
||||
default:
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
}
|
||||
#else
|
||||
(void)ucontext;
|
||||
return UNKNOWN; // FIXME: Implement.
|
||||
return Unknown; // FIXME: Implement.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -218,14 +218,12 @@ void InitTlsSize() { }
|
||||
// On glibc x86_64, ThreadDescriptorSize() needs to be precise due to the usage
|
||||
// of g_tls_size. On other targets, ThreadDescriptorSize() is only used by lsan
|
||||
// to get the pointer to thread-specific data keys in the thread control block.
|
||||
#if (SANITIZER_FREEBSD || SANITIZER_LINUX) && !SANITIZER_ANDROID
|
||||
#if (SANITIZER_FREEBSD || SANITIZER_LINUX) && !SANITIZER_ANDROID && !SANITIZER_GO
|
||||
// sizeof(struct pthread) from glibc.
|
||||
static atomic_uintptr_t thread_descriptor_size;
|
||||
|
||||
uptr ThreadDescriptorSize() {
|
||||
uptr val = atomic_load_relaxed(&thread_descriptor_size);
|
||||
if (val)
|
||||
return val;
|
||||
static uptr ThreadDescriptorSizeFallback() {
|
||||
uptr val = 0;
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
|
||||
int major;
|
||||
int minor;
|
||||
@ -287,8 +285,21 @@ uptr ThreadDescriptorSize() {
|
||||
#elif defined(__powerpc64__)
|
||||
val = 1776; // from glibc.ppc64le 2.20-8.fc21
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
|
||||
uptr ThreadDescriptorSize() {
|
||||
uptr val = atomic_load_relaxed(&thread_descriptor_size);
|
||||
if (val)
|
||||
atomic_store_relaxed(&thread_descriptor_size, val);
|
||||
return val;
|
||||
// _thread_db_sizeof_pthread is a GLIBC_PRIVATE symbol that is exported in
|
||||
// glibc 2.34 and later.
|
||||
if (unsigned *psizeof = static_cast<unsigned *>(
|
||||
dlsym(RTLD_DEFAULT, "_thread_db_sizeof_pthread")))
|
||||
val = *psizeof;
|
||||
if (!val)
|
||||
val = ThreadDescriptorSizeFallback();
|
||||
atomic_store_relaxed(&thread_descriptor_size, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -310,7 +321,6 @@ static uptr TlsPreTcbSize() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_GO
|
||||
namespace {
|
||||
struct TlsBlock {
|
||||
uptr begin, end, align;
|
||||
@ -398,9 +408,8 @@ __attribute__((unused)) static void GetStaticTlsBoundary(uptr *addr, uptr *size,
|
||||
*addr = ranges[l].begin;
|
||||
*size = ranges[r - 1].end - ranges[l].begin;
|
||||
}
|
||||
#endif // !SANITIZER_GO
|
||||
#endif // (x86_64 || i386 || mips || ...) && (SANITIZER_FREEBSD ||
|
||||
// SANITIZER_LINUX) && !SANITIZER_ANDROID
|
||||
// SANITIZER_LINUX) && !SANITIZER_ANDROID && !SANITIZER_GO
|
||||
|
||||
#if SANITIZER_NETBSD
|
||||
static struct tls_tcb * ThreadSelfTlsTcb() {
|
||||
|
@ -871,9 +871,9 @@ void LogFullErrorReport(const char *buffer) {
|
||||
SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
ucontext_t *ucontext = static_cast<ucontext_t*>(context);
|
||||
return ucontext->uc_mcontext->__es.__err & 2 /*T_PF_WRITE*/ ? WRITE : READ;
|
||||
return ucontext->uc_mcontext->__es.__err & 2 /*T_PF_WRITE*/ ? Write : Read;
|
||||
#else
|
||||
return UNKNOWN;
|
||||
return Unknown;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -211,9 +211,9 @@ static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid,
|
||||
Report("Hint: pc points to the zero page.\n");
|
||||
if (sig.is_memory_access) {
|
||||
const char *access_type =
|
||||
sig.write_flag == SignalContext::WRITE
|
||||
sig.write_flag == SignalContext::Write
|
||||
? "WRITE"
|
||||
: (sig.write_flag == SignalContext::READ ? "READ" : "UNKNOWN");
|
||||
: (sig.write_flag == SignalContext::Read ? "READ" : "UNKNOWN");
|
||||
Report("The signal is caused by a %s memory access.\n", access_type);
|
||||
if (!sig.is_true_faulting_addr)
|
||||
Report("Hint: this fault was caused by a dereference of a high value "
|
||||
|
@ -983,7 +983,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
|
||||
// The write flag is only available for access violation exceptions.
|
||||
if (exception_record->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
|
||||
// The contents of this array are documented at
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record
|
||||
@ -991,13 +991,13 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
||||
// second element is the faulting address.
|
||||
switch (exception_record->ExceptionInformation[0]) {
|
||||
case 0:
|
||||
return SignalContext::READ;
|
||||
return SignalContext::Read;
|
||||
case 1:
|
||||
return SignalContext::WRITE;
|
||||
return SignalContext::Write;
|
||||
case 8:
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
}
|
||||
return SignalContext::UNKNOWN;
|
||||
return SignalContext::Unknown;
|
||||
}
|
||||
|
||||
void SignalContext::DumpAllRegisters(void *context) {
|
||||
|
@ -1554,16 +1554,16 @@ TSAN_INTERCEPTOR(int, __fxstat, int version, int fd, void *buf) {
|
||||
#endif
|
||||
|
||||
TSAN_INTERCEPTOR(int, fstat, int fd, void *buf) {
|
||||
#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD
|
||||
SCOPED_TSAN_INTERCEPTOR(fstat, fd, buf);
|
||||
if (fd > 0)
|
||||
FdAccess(thr, pc, fd);
|
||||
return REAL(fstat)(fd, buf);
|
||||
#else
|
||||
#if SANITIZER_GLIBC
|
||||
SCOPED_TSAN_INTERCEPTOR(__fxstat, 0, fd, buf);
|
||||
if (fd > 0)
|
||||
FdAccess(thr, pc, fd);
|
||||
return REAL(__fxstat)(0, fd, buf);
|
||||
#else
|
||||
SCOPED_TSAN_INTERCEPTOR(fstat, fd, buf);
|
||||
if (fd > 0)
|
||||
FdAccess(thr, pc, fd);
|
||||
return REAL(fstat)(fd, buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
|
||||
@ -47,7 +47,7 @@ struct in_in_out_result {
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
|
||||
@ -47,7 +47,7 @@ struct in_out_result {
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -116,6 +116,8 @@
|
||||
# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT
|
||||
// Remove basic_string common base
|
||||
# define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON
|
||||
// Remove vector base class
|
||||
# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
|
||||
#elif _LIBCPP_ABI_VERSION == 1
|
||||
# if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
|
||||
// Enable compiling copies of now inline methods into the dylib to support
|
||||
|
@ -143,7 +143,7 @@ template <>
|
||||
_LIBCPP_AVAILABILITY_FILESYSTEM
|
||||
inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true;
|
||||
|
||||
#endif
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
|
@ -174,7 +174,7 @@ template <>
|
||||
_LIBCPP_AVAILABILITY_FILESYSTEM
|
||||
inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true;
|
||||
|
||||
#endif
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
|
@ -20,7 +20,8 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
|
||||
struct equal_to {
|
||||
@ -90,7 +91,7 @@ struct greater_equal {
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -64,7 +64,7 @@ void advance(_InputIter& __i, _Distance __orig_n) {
|
||||
_VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
|
||||
}
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
// [range.iter.op.advance]
|
||||
|
||||
@ -192,7 +192,7 @@ inline namespace __cpo {
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -52,7 +52,7 @@ distance(_InputIter __first, _InputIter __last)
|
||||
return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
|
||||
}
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
// [range.iter.op.distance]
|
||||
|
||||
@ -100,7 +100,7 @@ inline namespace __cpo {
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
template <class _Container>
|
||||
using __insert_iterator_iter_t = ranges::iterator_t<_Container>;
|
||||
#else
|
||||
|
@ -86,7 +86,7 @@ template<__dereferenceable _Tp>
|
||||
requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __referenceable; }
|
||||
using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<_Tp&>()));
|
||||
|
||||
#endif // !_LIBCPP_HAS_NO_CONCEPTS
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <__iterator/iter_move.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/readable_traits.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
#include <concepts>
|
||||
|
@ -35,7 +35,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
return __x;
|
||||
}
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
// [range.iter.op.next]
|
||||
|
||||
@ -79,7 +79,7 @@ inline namespace __cpo {
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -34,7 +34,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
return __x;
|
||||
}
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
// [range.iter.op.prev]
|
||||
|
||||
@ -71,7 +71,7 @@ inline namespace __cpo {
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -25,7 +25,8 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
|
||||
// [special.mem.concepts]
|
||||
@ -59,7 +60,8 @@ concept __nothrow_forward_range =
|
||||
__nothrow_forward_iterator<iterator_t<_Rp>>;
|
||||
|
||||
} // namespace ranges
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
namespace ranges {
|
||||
|
||||
// construct_at
|
||||
@ -117,7 +117,7 @@ inline namespace __cpo {
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -32,7 +32,8 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
|
||||
// uninitialized_default_construct
|
||||
@ -309,7 +310,8 @@ inline namespace __cpo {
|
||||
} // namespace __cpo
|
||||
|
||||
} // namespace ranges
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges::views {
|
||||
|
||||
@ -75,7 +75,7 @@ using all_t = decltype(views::all(declval<_Range>()));
|
||||
|
||||
} // namespace ranges::views
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
|
||||
@ -128,7 +128,7 @@ inline namespace __cpo {
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -35,13 +35,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
namespace ranges {
|
||||
|
||||
// [range.range]
|
||||
|
||||
template <class _Tp>
|
||||
concept range = requires(_Tp& __t) {
|
||||
ranges::begin(__t); // sometimes equality-preserving
|
||||
ranges::end(__t);
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
|
||||
|
||||
template<class _Range>
|
||||
concept borrowed_range = range<_Range> &&
|
||||
(is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>);
|
||||
@ -63,6 +68,8 @@ namespace ranges {
|
||||
template <range _Rp>
|
||||
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
// [range.sized]
|
||||
template <class _Tp>
|
||||
concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
|
||||
@ -93,9 +100,6 @@ namespace ranges {
|
||||
template <class _Rp, class _Tp>
|
||||
concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>;
|
||||
|
||||
template <class _Tp>
|
||||
concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
|
||||
|
||||
template <class _Tp>
|
||||
concept forward_range = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
|
||||
|
||||
@ -131,6 +135,8 @@ namespace ranges {
|
||||
(is_lvalue_reference_v<_Tp> ||
|
||||
(movable<remove_reference_t<_Tp>> && !__is_std_initializer_list<remove_cvref_t<_Tp>>))));
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
|
||||
// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
|
||||
@ -171,7 +171,7 @@ namespace ranges {
|
||||
};
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges::views {
|
||||
|
||||
@ -74,7 +74,7 @@ inline namespace __cpo {
|
||||
|
||||
} // namespace ranges::views
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -35,7 +35,7 @@ using borrowed_iterator_t = _If<borrowed_range<_Rp>, iterator_t<_Rp>, dangling>;
|
||||
// borrowed_subrange_t defined in <__ranges/subrange.h>
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !_LIBCPP_HAS_NO_CONCEPTS
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
// [range.prim.data]
|
||||
|
||||
@ -99,7 +99,7 @@ inline namespace __cpo {
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<view _View>
|
||||
@ -120,7 +120,7 @@ namespace ranges {
|
||||
inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
// [range.prim.empty]
|
||||
|
||||
@ -75,7 +75,7 @@ inline namespace __cpo {
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<class _Tp>
|
||||
@ -38,7 +38,7 @@ namespace ranges {
|
||||
inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -24,8 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
namespace ranges {
|
||||
|
||||
// [range.range], ranges
|
||||
|
||||
|
@ -40,7 +40,7 @@ inline constexpr bool enable_view = derived_from<_Tp, view_base> ||
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !_LIBCPP_HAS_NO_CONCEPTS
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<class _Int>
|
||||
@ -401,7 +401,7 @@ inline namespace __cpo {
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<class>
|
||||
@ -343,7 +343,7 @@ namespace ranges {
|
||||
|
||||
#undef _CONSTEXPR_TERNARY
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
// __non_propagating_cache is a helper type that allows storing an optional value in it,
|
||||
@ -107,7 +107,7 @@ namespace ranges {
|
||||
struct __empty_cache { };
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<range _Rp>
|
||||
@ -74,7 +74,7 @@ namespace ranges {
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
// CRTP base that one can derive from in order to be considered a range adaptor closure
|
||||
// by the library. When deriving from this class, a pipe operator will be provided to
|
||||
@ -66,7 +66,7 @@ struct __range_adaptor_closure {
|
||||
{ return __range_adaptor_closure_t(_VSTD::__compose(_VSTD::forward<_OtherClosure>(__c2), _VSTD::forward<_Closure>(__c1))); }
|
||||
};
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<range _Range>
|
||||
@ -79,7 +79,7 @@ namespace ranges {
|
||||
inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<view _View>
|
||||
@ -183,7 +183,7 @@ namespace ranges {
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<copy_constructible _Tp>
|
||||
@ -74,7 +74,7 @@ namespace ranges {
|
||||
single_view(_Tp) -> single_view<_Tp>;
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<class>
|
||||
@ -128,7 +128,7 @@ inline namespace __cpo {
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<class _From, class _To>
|
||||
@ -282,7 +282,7 @@ struct tuple_element<1, const ranges::subrange<_Ip, _Sp, _Kp>> {
|
||||
using type = _Sp;
|
||||
};
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -34,7 +34,7 @@ _LIBCPP_PUSH_MACROS
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
template<view _View>
|
||||
@ -176,7 +176,7 @@ namespace ranges {
|
||||
inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>;
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
|
||||
@ -433,7 +433,7 @@ inline namespace __cpo {
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
namespace ranges {
|
||||
|
||||
@ -188,7 +188,7 @@ class view_interface {
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -254,7 +254,6 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
@ -279,88 +278,74 @@ int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
|
||||
return 0;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return pthread_mutex_lock(__m);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return pthread_mutex_trylock(__m) == 0;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return pthread_mutex_unlock(__m);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return pthread_mutex_destroy(__m);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return pthread_mutex_lock(__m);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return pthread_mutex_trylock(__m) == 0;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return pthread_mutex_unlock(__m);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return pthread_mutex_destroy(__m);
|
||||
}
|
||||
|
||||
// Condition Variable
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
|
||||
{
|
||||
return pthread_cond_signal(__cv);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
|
||||
{
|
||||
return pthread_cond_broadcast(__cv);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
|
||||
{
|
||||
return pthread_cond_wait(__cv, __m);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
|
||||
__libcpp_timespec_t *__ts)
|
||||
{
|
||||
return pthread_cond_timedwait(__cv, __m, __ts);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
|
||||
{
|
||||
return pthread_cond_destroy(__cv);
|
||||
}
|
||||
|
||||
// Execute once
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
|
||||
void (*init_routine)()) {
|
||||
return pthread_once(flag, init_routine);
|
||||
@ -368,40 +353,34 @@ int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
|
||||
|
||||
// Thread id
|
||||
// Returns non-zero if the thread ids are equal, otherwise 0
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
{
|
||||
return t1 == t2;
|
||||
}
|
||||
|
||||
// Returns non-zero if t1 < t2, otherwise 0
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
{
|
||||
return t1 < t2;
|
||||
}
|
||||
|
||||
// Thread
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
|
||||
return __libcpp_thread_get_id(__t) == 0;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
|
||||
void *__arg)
|
||||
{
|
||||
return pthread_create(__t, nullptr, __func, __arg);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
__libcpp_thread_id __libcpp_thread_get_current_id()
|
||||
{
|
||||
const __libcpp_thread_t thread = pthread_self();
|
||||
return __libcpp_thread_get_id(&thread);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
|
||||
{
|
||||
#if defined(__MVS__)
|
||||
@ -411,25 +390,21 @@ __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
|
||||
#endif
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_thread_join(__libcpp_thread_t *__t)
|
||||
{
|
||||
return pthread_join(*__t, nullptr);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_thread_detach(__libcpp_thread_t *__t)
|
||||
{
|
||||
return pthread_detach(*__t);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
void __libcpp_thread_yield()
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
|
||||
{
|
||||
__libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
|
||||
@ -437,19 +412,16 @@ void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
|
||||
}
|
||||
|
||||
// Thread local storage
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
|
||||
{
|
||||
return pthread_key_create(__key, __at_exit);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
void *__libcpp_tls_get(__libcpp_tls_key __key)
|
||||
{
|
||||
return pthread_getspecific(__key);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
|
||||
{
|
||||
return pthread_setspecific(__key, __p);
|
||||
@ -457,56 +429,47 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
|
||||
|
||||
#elif defined(_LIBCPP_HAS_THREAD_API_C11)
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return mtx_trylock(__m) == thrd_success;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
mtx_destroy(__m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return mtx_trylock(__m) == thrd_success;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
|
||||
{
|
||||
mtx_destroy(__m);
|
||||
@ -514,25 +477,21 @@ int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
|
||||
}
|
||||
|
||||
// Condition Variable
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
|
||||
{
|
||||
return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
|
||||
{
|
||||
return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
|
||||
{
|
||||
return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
|
||||
timespec *__ts)
|
||||
{
|
||||
@ -540,7 +499,6 @@ int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
|
||||
return __ec == thrd_timedout ? ETIMEDOUT : __ec;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
|
||||
{
|
||||
cnd_destroy(__cv);
|
||||
@ -548,7 +506,6 @@ int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
|
||||
}
|
||||
|
||||
// Execute once
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
|
||||
void (*init_routine)(void)) {
|
||||
::call_once(flag, init_routine);
|
||||
@ -557,26 +514,22 @@ int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
|
||||
|
||||
// Thread id
|
||||
// Returns non-zero if the thread ids are equal, otherwise 0
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
{
|
||||
return thrd_equal(t1, t2) != 0;
|
||||
}
|
||||
|
||||
// Returns non-zero if t1 < t2, otherwise 0
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
{
|
||||
return t1 < t2;
|
||||
}
|
||||
|
||||
// Thread
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
|
||||
return __libcpp_thread_get_id(__t) == 0;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
|
||||
void *__arg)
|
||||
{
|
||||
@ -584,37 +537,31 @@ int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
|
||||
return __ec == thrd_nomem ? ENOMEM : __ec;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
__libcpp_thread_id __libcpp_thread_get_current_id()
|
||||
{
|
||||
return thrd_current();
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
|
||||
{
|
||||
return *__t;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_thread_join(__libcpp_thread_t *__t)
|
||||
{
|
||||
return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_thread_detach(__libcpp_thread_t *__t)
|
||||
{
|
||||
return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
void __libcpp_thread_yield()
|
||||
{
|
||||
thrd_yield();
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
|
||||
{
|
||||
__libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
|
||||
@ -622,19 +569,16 @@ void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
|
||||
}
|
||||
|
||||
// Thread local storage
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
|
||||
{
|
||||
return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
void *__libcpp_tls_get(__libcpp_tls_key __key)
|
||||
{
|
||||
return tss_get(__key);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline
|
||||
int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
|
||||
{
|
||||
return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
|
||||
|
@ -200,11 +200,6 @@ namespace std::ranges {
|
||||
|
||||
*/
|
||||
|
||||
// Make sure all feature-test macros are available.
|
||||
#include <version>
|
||||
// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
#include <__config>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/all.h>
|
||||
@ -232,19 +227,18 @@ namespace std::ranges {
|
||||
#include <initializer_list> // Required by the standard.
|
||||
#include <iterator> // Required by the standard.
|
||||
#include <type_traits>
|
||||
#include <version>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
namespace views = ranges::views;
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
@ -170,7 +170,7 @@ struct __is_std_span : false_type {};
|
||||
template <class _Tp, size_t _Sz>
|
||||
struct __is_std_span<span<_Tp, _Sz>> : true_type {};
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
template <class _Range, class _ElementType>
|
||||
concept __span_compatible_range =
|
||||
ranges::contiguous_range<_Range> &&
|
||||
@ -234,7 +234,7 @@ public:
|
||||
_LIBCPP_ASSERT(__last - __first == _Extent,
|
||||
"invalid range in span's constructor (iterator, sentinel): last - first != extent");
|
||||
}
|
||||
#endif
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data{__arr} {}
|
||||
|
||||
@ -248,13 +248,13 @@ public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
template <__span_compatible_range<element_type> _Range>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr explicit span(_Range&& __r) : __data{ranges::data(__r)} {
|
||||
_LIBCPP_ASSERT(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");
|
||||
}
|
||||
#endif
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
template <class _OtherElementType>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@ -418,7 +418,7 @@ public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr span(_It __first, _End __last)
|
||||
: __data(_VSTD::to_address(__first)), __size(__last - __first) {}
|
||||
#endif
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
template <size_t _Sz>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@ -434,11 +434,11 @@ public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
template <__span_compatible_range<element_type> _Range>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr span(_Range&& __r) : __data(ranges::data(__r)), __size{ranges::size(__r)} {}
|
||||
# endif
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
|
||||
template <class _OtherElementType, size_t _OtherExtent>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@ -565,10 +565,9 @@ auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept
|
||||
{ return __s.__as_writable_bytes(); }
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
// Deduction guides
|
||||
template<contiguous_iterator _It, class _EndOrSize>
|
||||
span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>;
|
||||
#endif
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
template<class _Tp, size_t _Sz>
|
||||
span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;
|
||||
@ -579,7 +578,7 @@ template<class _Tp, size_t _Sz>
|
||||
template<class _Tp, size_t _Sz>
|
||||
span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>;
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
template<ranges::contiguous_range _Range>
|
||||
span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>;
|
||||
#endif
|
||||
|
@ -2897,6 +2897,10 @@ template <class _CharT, class _Traits, class _Allocator>
|
||||
typename basic_string<_CharT, _Traits, _Allocator>::iterator
|
||||
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
|
||||
{
|
||||
_LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
|
||||
"string::insert(iterator, character) called with an iterator not"
|
||||
" referring to this string");
|
||||
|
||||
size_type __ip = static_cast<size_type>(__pos - begin());
|
||||
size_type __sz = size();
|
||||
size_type __cap = capacity();
|
||||
|
@ -294,9 +294,9 @@ public:
|
||||
{
|
||||
_LIBCPP_ASSERT((__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range");
|
||||
}
|
||||
#endif
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
template <class _Range>
|
||||
requires (
|
||||
!is_same_v<remove_cvref_t<_Range>, basic_string_view> &&
|
||||
@ -720,10 +720,10 @@ inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _T
|
||||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
|
||||
basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
|
||||
#endif
|
||||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
|
||||
|
||||
#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
|
||||
#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
|
||||
template <ranges::contiguous_range _Range>
|
||||
basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;
|
||||
#endif
|
||||
|
@ -302,55 +302,10 @@ _LIBCPP_PUSH_MACROS
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <bool>
|
||||
struct __vector_base_common;
|
||||
|
||||
template <>
|
||||
struct __vector_base_common<true> {
|
||||
// Both are defined in vector.cpp
|
||||
_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const;
|
||||
_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const;
|
||||
};
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
class __vector_base
|
||||
: protected __vector_base_common<true> // This base class is historical, but it needs to remain for ABI compatibility
|
||||
{
|
||||
typedef _Allocator allocator_type;
|
||||
typedef typename allocator_traits<allocator_type>::pointer pointer;
|
||||
|
||||
protected:
|
||||
pointer __begin_;
|
||||
pointer __end_;
|
||||
__compressed_pair<pointer, allocator_type> __end_cap_;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__vector_base()
|
||||
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
|
||||
: __begin_(nullptr),
|
||||
__end_(nullptr),
|
||||
__end_cap_(nullptr, __default_init_tag()) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a)
|
||||
: __begin_(nullptr),
|
||||
__end_(nullptr),
|
||||
__end_cap_(nullptr, __a) {}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
_LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT
|
||||
: __begin_(nullptr),
|
||||
__end_(nullptr),
|
||||
__end_cap_(nullptr, _VSTD::move(__a)) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class _Tp, class _Allocator /* = allocator<_Tp> */>
|
||||
class _LIBCPP_TEMPLATE_VIS vector
|
||||
// This base class is historical, but it needs to remain for ABI compatibility.
|
||||
: private __vector_base<_Tp, _Allocator>
|
||||
{
|
||||
private:
|
||||
typedef __vector_base<_Tp, _Allocator> __base;
|
||||
typedef allocator<_Tp> __default_allocator_type;
|
||||
public:
|
||||
typedef vector __self;
|
||||
@ -382,7 +337,7 @@ public:
|
||||
#else
|
||||
_NOEXCEPT
|
||||
#endif
|
||||
: __base(__a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
}
|
||||
@ -394,7 +349,7 @@ public:
|
||||
|
||||
template <class = __enable_if_t<__is_allocator<_Allocator>::value> >
|
||||
vector(size_type __n, const value_type& __x, const allocator_type& __a)
|
||||
: __base(__a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
if (__n > 0)
|
||||
@ -691,6 +646,11 @@ public:
|
||||
#endif // _LIBCPP_DEBUG_LEVEL == 2
|
||||
|
||||
private:
|
||||
pointer __begin_ = nullptr;
|
||||
pointer __end_ = nullptr;
|
||||
__compressed_pair<pointer, allocator_type> __end_cap_ =
|
||||
__compressed_pair<pointer, allocator_type>(nullptr, __default_init_tag());
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
|
||||
_LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(pointer __new_last);
|
||||
void __vallocate(size_type __n);
|
||||
@ -859,20 +819,12 @@ private:
|
||||
|
||||
_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
|
||||
void __throw_length_error() const {
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
__vector_base_common<true>::__throw_length_error();
|
||||
#else
|
||||
_VSTD::abort();
|
||||
#endif
|
||||
_VSTD::__throw_length_error("vector");
|
||||
}
|
||||
|
||||
_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
|
||||
void __throw_out_of_range() const {
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
__vector_base_common<true>::__throw_out_of_range();
|
||||
#else
|
||||
_VSTD::abort();
|
||||
#endif
|
||||
_VSTD::__throw_out_of_range("vector");
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@ -1106,7 +1058,7 @@ vector<_Tp, _Allocator>::vector(size_type __n)
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
template <class _Tp, class _Allocator>
|
||||
vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
|
||||
: __base(__a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
if (__n > 0)
|
||||
@ -1151,7 +1103,7 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, c
|
||||
is_constructible<
|
||||
value_type,
|
||||
typename iterator_traits<_InputIterator>::reference>::value>::type*)
|
||||
: __base(__a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
for (; __first != __last; ++__first)
|
||||
@ -1183,7 +1135,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las
|
||||
is_constructible<
|
||||
value_type,
|
||||
typename iterator_traits<_ForwardIterator>::reference>::value>::type*)
|
||||
: __base(__a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
||||
@ -1196,7 +1148,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
vector<_Tp, _Allocator>::vector(const vector& __x)
|
||||
: __base(__alloc_traits::select_on_container_copy_construction(__x.__alloc()))
|
||||
: __end_cap_(nullptr, __alloc_traits::select_on_container_copy_construction(__x.__alloc()))
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
size_type __n = __x.size();
|
||||
@ -1209,7 +1161,7 @@ vector<_Tp, _Allocator>::vector(const vector& __x)
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
vector<_Tp, _Allocator>::vector(const vector& __x, const __identity_t<allocator_type>& __a)
|
||||
: __base(__a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
size_type __n = __x.size();
|
||||
@ -1230,7 +1182,7 @@ vector<_Tp, _Allocator>::vector(vector&& __x)
|
||||
#else
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
|
||||
#endif
|
||||
: __base(_VSTD::move(__x.__alloc()))
|
||||
: __end_cap_(nullptr, _VSTD::move(__x.__alloc()))
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
#if _LIBCPP_DEBUG_LEVEL == 2
|
||||
@ -1245,7 +1197,7 @@ vector<_Tp, _Allocator>::vector(vector&& __x)
|
||||
template <class _Tp, class _Allocator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
vector<_Tp, _Allocator>::vector(vector&& __x, const __identity_t<allocator_type>& __a)
|
||||
: __base(__a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
if (__a == __x.__alloc())
|
||||
@ -1280,7 +1232,7 @@ vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
|
||||
template <class _Tp, class _Allocator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
|
||||
: __base(__a)
|
||||
: __end_cap_(nullptr, __a)
|
||||
{
|
||||
_VSTD::__debug_db_insert_c(this);
|
||||
if (__il.size() > 0)
|
||||
@ -2079,7 +2031,6 @@ struct __has_storage_type<vector<bool, _Allocator> >
|
||||
|
||||
template <class _Allocator>
|
||||
class _LIBCPP_TEMPLATE_VIS vector<bool, _Allocator>
|
||||
: private __vector_base_common<true>
|
||||
{
|
||||
public:
|
||||
typedef vector __self;
|
||||
@ -2348,6 +2299,16 @@ public:
|
||||
bool __invariants() const;
|
||||
|
||||
private:
|
||||
_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
|
||||
void __throw_length_error() const {
|
||||
_VSTD::__throw_length_error("vector");
|
||||
}
|
||||
|
||||
_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
|
||||
void __throw_out_of_range() const {
|
||||
_VSTD::__throw_out_of_range("vector");
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
|
||||
void __vallocate(size_type __n);
|
||||
void __vdeallocate() _NOEXCEPT;
|
||||
|
@ -10,12 +10,25 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
|
||||
|
||||
template <bool>
|
||||
struct __vector_base_common;
|
||||
|
||||
template <>
|
||||
struct __vector_base_common<true> {
|
||||
_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_length_error() const;
|
||||
_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_out_of_range() const;
|
||||
};
|
||||
|
||||
void __vector_base_common<true>::__throw_length_error() const {
|
||||
_VSTD::__throw_length_error("vector");
|
||||
_VSTD::__throw_length_error("vector");
|
||||
}
|
||||
|
||||
void __vector_base_common<true>::__throw_out_of_range() const {
|
||||
_VSTD::__throw_out_of_range("vector");
|
||||
_VSTD::__throw_out_of_range("vector");
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC 31
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64 31
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143
|
||||
@ -125,6 +126,12 @@
|
||||
# error "Unsupported MIPS ABI and/or environment"
|
||||
# endif
|
||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS
|
||||
#elif defined(__sparc__) && defined(__arch64__)
|
||||
#define _LIBUNWIND_TARGET_SPARC64 1
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER \
|
||||
_LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64
|
||||
#define _LIBUNWIND_CONTEXT_SIZE 33
|
||||
#define _LIBUNWIND_CURSOR_SIZE 45
|
||||
# elif defined(__sparc__)
|
||||
#define _LIBUNWIND_TARGET_SPARC 1
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC
|
||||
@ -165,6 +172,7 @@
|
||||
# define _LIBUNWIND_TARGET_MIPS_O32 1
|
||||
# define _LIBUNWIND_TARGET_MIPS_NEWABI 1
|
||||
# define _LIBUNWIND_TARGET_SPARC 1
|
||||
# define _LIBUNWIND_TARGET_SPARC64 1
|
||||
# define _LIBUNWIND_TARGET_HEXAGON 1
|
||||
# define _LIBUNWIND_TARGET_RISCV 1
|
||||
# define _LIBUNWIND_TARGET_VE 1
|
||||
|
@ -74,6 +74,13 @@ class DwarfInstructions {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
auto getSparcWCookie(const R &r, int) -> decltype(r.getWCookie()) {
|
||||
return r.getWCookie();
|
||||
}
|
||||
template <typename R> uint64_t getSparcWCookie(const R &, long) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename A, typename R>
|
||||
typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
|
||||
@ -83,6 +90,10 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
|
||||
case CFI_Parser<A>::kRegisterInCFA:
|
||||
return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value);
|
||||
|
||||
case CFI_Parser<A>::kRegisterInCFADecrypt: // sparc64 specific
|
||||
return (pint_t)(addressSpace.getP(cfa + (pint_t)savedReg.value) ^
|
||||
getSparcWCookie(registers, 0));
|
||||
|
||||
case CFI_Parser<A>::kRegisterAtExpression:
|
||||
return (pint_t)addressSpace.getRegister(evaluateExpression(
|
||||
(pint_t)savedReg.value, addressSpace, registers, cfa));
|
||||
@ -121,6 +132,7 @@ double DwarfInstructions<A, R>::getSavedFloatRegister(
|
||||
case CFI_Parser<A>::kRegisterIsExpression:
|
||||
case CFI_Parser<A>::kRegisterUnused:
|
||||
case CFI_Parser<A>::kRegisterOffsetFromCFA:
|
||||
case CFI_Parser<A>::kRegisterInCFADecrypt:
|
||||
// FIX ME
|
||||
break;
|
||||
}
|
||||
@ -144,6 +156,7 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
|
||||
case CFI_Parser<A>::kRegisterUnused:
|
||||
case CFI_Parser<A>::kRegisterOffsetFromCFA:
|
||||
case CFI_Parser<A>::kRegisterInRegister:
|
||||
case CFI_Parser<A>::kRegisterInCFADecrypt:
|
||||
// FIX ME
|
||||
break;
|
||||
}
|
||||
@ -258,6 +271,12 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
// Skip call site instruction and delay slot.
|
||||
if (R::getArch() == REGISTERS_SPARC64)
|
||||
returnAddress += 8;
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_PPC64)
|
||||
#define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1)
|
||||
#define PPC64_ELFV1_R2_OFFSET 40
|
||||
|
@ -70,6 +70,7 @@ class CFI_Parser {
|
||||
enum RegisterSavedWhere {
|
||||
kRegisterUnused,
|
||||
kRegisterInCFA,
|
||||
kRegisterInCFADecrypt, // sparc64 specific
|
||||
kRegisterOffsetFromCFA,
|
||||
kRegisterInRegister,
|
||||
kRegisterAtExpression,
|
||||
@ -732,7 +733,8 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
|
||||
"DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset);
|
||||
break;
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC)
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC) || \
|
||||
defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
// The same constant is used to represent different instructions on
|
||||
// AArch64 (negate_ra_state) and SPARC (window_save).
|
||||
static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save,
|
||||
@ -766,8 +768,31 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
// case DW_CFA_GNU_window_save:
|
||||
case REGISTERS_SPARC64:
|
||||
// Don't save %o0-%o7 on sparc64.
|
||||
// https://reviews.llvm.org/D32450#736405
|
||||
|
||||
for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
|
||||
if (reg == UNW_SPARC_I7)
|
||||
results->setRegister(
|
||||
reg, kRegisterInCFADecrypt,
|
||||
static_cast<int64_t>((reg - UNW_SPARC_L0) * sizeof(pint_t)),
|
||||
initialState);
|
||||
else
|
||||
results->setRegister(
|
||||
reg, kRegisterInCFA,
|
||||
static_cast<int64_t>((reg - UNW_SPARC_L0) * sizeof(pint_t)),
|
||||
initialState);
|
||||
}
|
||||
_LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save\n");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
#else
|
||||
(void)arch;
|
||||
#endif
|
||||
|
@ -35,6 +35,7 @@ enum {
|
||||
REGISTERS_MIPS_O32,
|
||||
REGISTERS_MIPS_NEWABI,
|
||||
REGISTERS_SPARC,
|
||||
REGISTERS_SPARC64,
|
||||
REGISTERS_HEXAGON,
|
||||
REGISTERS_RISCV,
|
||||
REGISTERS_VE,
|
||||
@ -3586,6 +3587,191 @@ inline const char *Registers_sparc::getRegisterName(int regNum) {
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_SPARC
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
/// Registers_sparc64 holds the register state of a thread in a 64-bit
|
||||
/// sparc process.
|
||||
class _LIBUNWIND_HIDDEN Registers_sparc64 {
|
||||
public:
|
||||
Registers_sparc64() = default;
|
||||
Registers_sparc64(const void *registers);
|
||||
|
||||
bool validRegister(int num) const;
|
||||
uint64_t getRegister(int num) const;
|
||||
void setRegister(int num, uint64_t value);
|
||||
bool validFloatRegister(int num) const;
|
||||
double getFloatRegister(int num) const;
|
||||
void setFloatRegister(int num, double value);
|
||||
bool validVectorRegister(int num) const;
|
||||
v128 getVectorRegister(int num) const;
|
||||
void setVectorRegister(int num, v128 value);
|
||||
const char *getRegisterName(int num);
|
||||
void jumpto();
|
||||
static int lastDwarfRegNum() {
|
||||
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64;
|
||||
}
|
||||
static int getArch() { return REGISTERS_SPARC64; }
|
||||
|
||||
uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6] + 2047; }
|
||||
void setSP(uint64_t value) { _registers.__regs[UNW_SPARC_O6] = value - 2047; }
|
||||
uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
|
||||
void setIP(uint64_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
|
||||
uint64_t getWCookie() const { return _wcookie; }
|
||||
|
||||
private:
|
||||
struct sparc64_thread_state_t {
|
||||
uint64_t __regs[32];
|
||||
};
|
||||
|
||||
sparc64_thread_state_t _registers{};
|
||||
uint64_t _wcookie = 0;
|
||||
};
|
||||
|
||||
inline Registers_sparc64::Registers_sparc64(const void *registers) {
|
||||
static_assert((check_fit<Registers_sparc64, unw_context_t>::does_fit),
|
||||
"sparc64 registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, registers, sizeof(_registers));
|
||||
memcpy(&_wcookie,
|
||||
static_cast<const uint8_t *>(registers) + sizeof(_registers),
|
||||
sizeof(_wcookie));
|
||||
}
|
||||
|
||||
inline bool Registers_sparc64::validRegister(int regNum) const {
|
||||
if (regNum == UNW_REG_IP)
|
||||
return true;
|
||||
if (regNum == UNW_REG_SP)
|
||||
return true;
|
||||
if (regNum < 0)
|
||||
return false;
|
||||
if (regNum <= UNW_SPARC_I7)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline uint64_t Registers_sparc64::getRegister(int regNum) const {
|
||||
if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7)
|
||||
return _registers.__regs[regNum];
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
return _registers.__regs[UNW_SPARC_O7];
|
||||
case UNW_REG_SP:
|
||||
return _registers.__regs[UNW_SPARC_O6] + 2047;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported sparc64 register");
|
||||
}
|
||||
|
||||
inline void Registers_sparc64::setRegister(int regNum, uint64_t value) {
|
||||
if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7) {
|
||||
_registers.__regs[regNum] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
_registers.__regs[UNW_SPARC_O7] = value;
|
||||
return;
|
||||
case UNW_REG_SP:
|
||||
_registers.__regs[UNW_SPARC_O6] = value - 2047;
|
||||
return;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported sparc64 register");
|
||||
}
|
||||
|
||||
inline bool Registers_sparc64::validFloatRegister(int) const { return false; }
|
||||
|
||||
inline double Registers_sparc64::getFloatRegister(int) const {
|
||||
_LIBUNWIND_ABORT("no sparc64 float registers");
|
||||
}
|
||||
|
||||
inline void Registers_sparc64::setFloatRegister(int, double) {
|
||||
_LIBUNWIND_ABORT("no sparc64 float registers");
|
||||
}
|
||||
|
||||
inline bool Registers_sparc64::validVectorRegister(int) const { return false; }
|
||||
|
||||
inline v128 Registers_sparc64::getVectorRegister(int) const {
|
||||
_LIBUNWIND_ABORT("no sparc64 vector registers");
|
||||
}
|
||||
|
||||
inline void Registers_sparc64::setVectorRegister(int, v128) {
|
||||
_LIBUNWIND_ABORT("no sparc64 vector registers");
|
||||
}
|
||||
|
||||
inline const char *Registers_sparc64::getRegisterName(int regNum) {
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
return "pc";
|
||||
case UNW_SPARC_G0:
|
||||
return "g0";
|
||||
case UNW_SPARC_G1:
|
||||
return "g1";
|
||||
case UNW_SPARC_G2:
|
||||
return "g2";
|
||||
case UNW_SPARC_G3:
|
||||
return "g3";
|
||||
case UNW_SPARC_G4:
|
||||
return "g4";
|
||||
case UNW_SPARC_G5:
|
||||
return "g5";
|
||||
case UNW_SPARC_G6:
|
||||
return "g6";
|
||||
case UNW_SPARC_G7:
|
||||
return "g7";
|
||||
case UNW_SPARC_O0:
|
||||
return "o0";
|
||||
case UNW_SPARC_O1:
|
||||
return "o1";
|
||||
case UNW_SPARC_O2:
|
||||
return "o2";
|
||||
case UNW_SPARC_O3:
|
||||
return "o3";
|
||||
case UNW_SPARC_O4:
|
||||
return "o4";
|
||||
case UNW_SPARC_O5:
|
||||
return "o5";
|
||||
case UNW_REG_SP:
|
||||
case UNW_SPARC_O6:
|
||||
return "o6";
|
||||
case UNW_SPARC_O7:
|
||||
return "o7";
|
||||
case UNW_SPARC_L0:
|
||||
return "l0";
|
||||
case UNW_SPARC_L1:
|
||||
return "l1";
|
||||
case UNW_SPARC_L2:
|
||||
return "l2";
|
||||
case UNW_SPARC_L3:
|
||||
return "l3";
|
||||
case UNW_SPARC_L4:
|
||||
return "l4";
|
||||
case UNW_SPARC_L5:
|
||||
return "l5";
|
||||
case UNW_SPARC_L6:
|
||||
return "l6";
|
||||
case UNW_SPARC_L7:
|
||||
return "l7";
|
||||
case UNW_SPARC_I0:
|
||||
return "i0";
|
||||
case UNW_SPARC_I1:
|
||||
return "i1";
|
||||
case UNW_SPARC_I2:
|
||||
return "i2";
|
||||
case UNW_SPARC_I3:
|
||||
return "i3";
|
||||
case UNW_SPARC_I4:
|
||||
return "i4";
|
||||
case UNW_SPARC_I5:
|
||||
return "i5";
|
||||
case UNW_SPARC_I6:
|
||||
return "i6";
|
||||
case UNW_SPARC_I7:
|
||||
return "i7";
|
||||
default:
|
||||
return "unknown register";
|
||||
}
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_SPARC64
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_HEXAGON)
|
||||
/// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
|
||||
/// process.
|
||||
|
@ -1032,6 +1032,10 @@ class UnwindCursor : public AbstractUnwindCursor{
|
||||
int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; }
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
int stepWithCompactEncoding(Registers_sparc64 &) { return UNW_EINVAL; }
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_RISCV)
|
||||
int stepWithCompactEncoding(Registers_riscv &) {
|
||||
return UNW_EINVAL;
|
||||
@ -1104,6 +1108,12 @@ class UnwindCursor : public AbstractUnwindCursor{
|
||||
bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
bool compactSaysUseDwarf(Registers_sparc64 &, uint32_t *) const {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_RISCV)
|
||||
bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const {
|
||||
return true;
|
||||
@ -1182,6 +1192,12 @@ class UnwindCursor : public AbstractUnwindCursor{
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_sparc64 &) const {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_RISCV)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const {
|
||||
return 0;
|
||||
|
@ -1062,6 +1062,53 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv)
|
||||
ld $4, (8 * 4)($4)
|
||||
.set pop
|
||||
|
||||
#elif defined(__sparc__) && defined(__arch64__)
|
||||
|
||||
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_sparc646jumptoEv)
|
||||
//
|
||||
// void libunwind::Registers_sparc64::jumpto()
|
||||
//
|
||||
// On entry:
|
||||
// thread_state pointer is in %o0
|
||||
//
|
||||
.register %g2, #scratch
|
||||
.register %g3, #scratch
|
||||
.register %g6, #scratch
|
||||
.register %g7, #scratch
|
||||
flushw
|
||||
ldx [%o0 + 0x08], %g1
|
||||
ldx [%o0 + 0x10], %g2
|
||||
ldx [%o0 + 0x18], %g3
|
||||
ldx [%o0 + 0x20], %g4
|
||||
ldx [%o0 + 0x28], %g5
|
||||
ldx [%o0 + 0x30], %g6
|
||||
ldx [%o0 + 0x38], %g7
|
||||
ldx [%o0 + 0x48], %o1
|
||||
ldx [%o0 + 0x50], %o2
|
||||
ldx [%o0 + 0x58], %o3
|
||||
ldx [%o0 + 0x60], %o4
|
||||
ldx [%o0 + 0x68], %o5
|
||||
ldx [%o0 + 0x70], %o6
|
||||
ldx [%o0 + 0x78], %o7
|
||||
ldx [%o0 + 0x80], %l0
|
||||
ldx [%o0 + 0x88], %l1
|
||||
ldx [%o0 + 0x90], %l2
|
||||
ldx [%o0 + 0x98], %l3
|
||||
ldx [%o0 + 0xa0], %l4
|
||||
ldx [%o0 + 0xa8], %l5
|
||||
ldx [%o0 + 0xb0], %l6
|
||||
ldx [%o0 + 0xb8], %l7
|
||||
ldx [%o0 + 0xc0], %i0
|
||||
ldx [%o0 + 0xc8], %i1
|
||||
ldx [%o0 + 0xd0], %i2
|
||||
ldx [%o0 + 0xd8], %i3
|
||||
ldx [%o0 + 0xe0], %i4
|
||||
ldx [%o0 + 0xe8], %i5
|
||||
ldx [%o0 + 0xf0], %i6
|
||||
ldx [%o0 + 0xf8], %i7
|
||||
jmp %o7
|
||||
ldx [%o0 + 0x40], %o0
|
||||
|
||||
#elif defined(__sparc__)
|
||||
|
||||
//
|
||||
|
@ -999,6 +999,64 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||
|
||||
jumpr r31
|
||||
|
||||
#elif defined(__sparc__) && defined(__arch64__)
|
||||
|
||||
#
|
||||
# extern int __unw_getcontext(unw_context_t* thread_state)
|
||||
#
|
||||
# On entry:
|
||||
# thread_state pointer is in %o0
|
||||
#
|
||||
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||
.register %g2, #scratch
|
||||
.register %g3, #scratch
|
||||
.register %g6, #scratch
|
||||
.register %g7, #scratch
|
||||
stx %g1, [%o0 + 0x08]
|
||||
stx %g2, [%o0 + 0x10]
|
||||
stx %g3, [%o0 + 0x18]
|
||||
stx %g4, [%o0 + 0x20]
|
||||
stx %g5, [%o0 + 0x28]
|
||||
stx %g6, [%o0 + 0x30]
|
||||
stx %g7, [%o0 + 0x38]
|
||||
stx %o0, [%o0 + 0x40]
|
||||
stx %o1, [%o0 + 0x48]
|
||||
stx %o2, [%o0 + 0x50]
|
||||
stx %o3, [%o0 + 0x58]
|
||||
stx %o4, [%o0 + 0x60]
|
||||
stx %o5, [%o0 + 0x68]
|
||||
stx %o6, [%o0 + 0x70]
|
||||
stx %o7, [%o0 + 0x78]
|
||||
stx %l0, [%o0 + 0x80]
|
||||
stx %l1, [%o0 + 0x88]
|
||||
stx %l2, [%o0 + 0x90]
|
||||
stx %l3, [%o0 + 0x98]
|
||||
stx %l4, [%o0 + 0xa0]
|
||||
stx %l5, [%o0 + 0xa8]
|
||||
stx %l6, [%o0 + 0xb0]
|
||||
stx %l7, [%o0 + 0xb8]
|
||||
stx %i0, [%o0 + 0xc0]
|
||||
stx %i1, [%o0 + 0xc8]
|
||||
stx %i2, [%o0 + 0xd0]
|
||||
stx %i3, [%o0 + 0xd8]
|
||||
stx %i4, [%o0 + 0xe0]
|
||||
stx %i5, [%o0 + 0xe8]
|
||||
stx %i6, [%o0 + 0xf0]
|
||||
stx %i7, [%o0 + 0xf8]
|
||||
|
||||
# save StackGhost cookie
|
||||
mov %i7, %g4
|
||||
save %sp, -176, %sp
|
||||
# register window flush necessary even without StackGhost
|
||||
flushw
|
||||
restore
|
||||
ldx [%sp + 2047 + 0x78], %g5
|
||||
xor %g4, %g5, %g4
|
||||
stx %g4, [%o0 + 0x100]
|
||||
retl
|
||||
# return UNW_ESUCCESS
|
||||
clr %o0
|
||||
|
||||
#elif defined(__sparc__)
|
||||
|
||||
#
|
||||
|
@ -109,13 +109,10 @@
|
||||
#define _LIBUNWIND_SUPPORT_FRAME_APIS
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) || \
|
||||
defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \
|
||||
(!defined(__APPLE__) && defined(__arm__)) || \
|
||||
defined(__aarch64__) || \
|
||||
defined(__mips__) || \
|
||||
defined(__riscv) || \
|
||||
defined(__hexagon__)
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \
|
||||
(!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \
|
||||
defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \
|
||||
defined(__sparc__)
|
||||
#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS
|
||||
#endif
|
||||
|
@ -67,6 +67,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
|
||||
# define REGISTER_KIND Registers_mips_newabi
|
||||
#elif defined(__mips__)
|
||||
# warning The MIPS architecture is not supported with this ABI and environment!
|
||||
#elif defined(__sparc__) && defined(__arch64__)
|
||||
#define REGISTER_KIND Registers_sparc64
|
||||
#elif defined(__sparc__)
|
||||
# define REGISTER_KIND Registers_sparc
|
||||
#elif defined(__riscv)
|
||||
|
@ -1385,9 +1385,10 @@ bool PPC64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
|
||||
if (type == R_PPC64_REL24_NOTOC && (s.stOther >> 5) > 1)
|
||||
return true;
|
||||
|
||||
// If a symbol is a weak undefined and we are compiling an executable
|
||||
// it doesn't need a range-extending thunk since it can't be called.
|
||||
if (s.isUndefWeak() && !config->shared)
|
||||
// An undefined weak symbol not in a PLT does not need a thunk. If it is
|
||||
// hidden, its binding has been converted to local, so we just check
|
||||
// isUndefined() here. A undefined non-weak symbol has been errored.
|
||||
if (s.isUndefined())
|
||||
return false;
|
||||
|
||||
// If the offset exceeds the range of the branch type then it will need
|
||||
|
@ -235,22 +235,28 @@ void LinkerDriver::addFile(StringRef path, bool withLOption) {
|
||||
// user is attempting LTO and using a default ar command that doesn't
|
||||
// understand the LLVM bitcode file. Treat the archive as a group of lazy
|
||||
// object files.
|
||||
if (!file->isEmpty() && !file->hasSymbolTable()) {
|
||||
for (const std::pair<MemoryBufferRef, uint64_t> &p :
|
||||
getArchiveMembers(mbref)) {
|
||||
auto magic = identify_magic(p.first.getBuffer());
|
||||
if (magic == file_magic::bitcode ||
|
||||
magic == file_magic::elf_relocatable)
|
||||
files.push_back(createLazyFile(p.first, path, p.second));
|
||||
else
|
||||
error(path + ": archive member '" + p.first.getBufferIdentifier() +
|
||||
"' is neither ET_REL nor LLVM bitcode");
|
||||
}
|
||||
if (file->isEmpty() || file->hasSymbolTable()) {
|
||||
// Handle the regular case.
|
||||
files.push_back(make<ArchiveFile>(std::move(file)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle the regular case.
|
||||
files.push_back(make<ArchiveFile>(std::move(file)));
|
||||
// All files within the archive get the same group ID to allow mutual
|
||||
// references for --warn-backrefs.
|
||||
bool saved = InputFile::isInGroup;
|
||||
InputFile::isInGroup = true;
|
||||
for (const std::pair<MemoryBufferRef, uint64_t> &p :
|
||||
getArchiveMembers(mbref)) {
|
||||
auto magic = identify_magic(p.first.getBuffer());
|
||||
if (magic == file_magic::bitcode || magic == file_magic::elf_relocatable)
|
||||
files.push_back(createLazyFile(p.first, path, p.second));
|
||||
else
|
||||
error(path + ": archive member '" + p.first.getBufferIdentifier() +
|
||||
"' is neither ET_REL nor LLVM bitcode");
|
||||
}
|
||||
InputFile::isInGroup = saved;
|
||||
if (!saved)
|
||||
++InputFile::nextGroupId;
|
||||
return;
|
||||
}
|
||||
case file_magic::elf_shared_object:
|
||||
@ -1234,6 +1240,9 @@ static void readConfigs(opt::InputArgList &args) {
|
||||
error(errPrefix + toString(pat.takeError()));
|
||||
}
|
||||
|
||||
if (args.hasArg(OPT_define_common, OPT_no_define_common))
|
||||
warn("-d, -dc, -dp, and --[no-]define-common will be removed. See https://github.com/llvm/llvm-project/issues/53660");
|
||||
|
||||
cl::ResetAllOptionOccurrences();
|
||||
|
||||
// Parse LTO options.
|
||||
|
@ -152,18 +152,17 @@ static bool isCompatible(InputFile *file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InputFile *existing;
|
||||
InputFile *existing = nullptr;
|
||||
if (!objectFiles.empty())
|
||||
existing = objectFiles[0];
|
||||
else if (!sharedFiles.empty())
|
||||
existing = sharedFiles[0];
|
||||
else if (!bitcodeFiles.empty())
|
||||
existing = bitcodeFiles[0];
|
||||
else
|
||||
llvm_unreachable("Must have -m, OUTPUT_FORMAT or existing input file to "
|
||||
"determine target emulation");
|
||||
|
||||
error(toString(file) + " is incompatible with " + toString(existing));
|
||||
std::string with;
|
||||
if (existing)
|
||||
with = " with " + toString(existing);
|
||||
error(toString(file) + " is incompatible" + with);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "lld/Common/Memory.h"
|
||||
#include "lld/Common/Strings.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/Config/config.h" // LLVM_ENABLE_ZLIB
|
||||
#include "llvm/Config/llvm-config.h" // LLVM_ENABLE_ZLIB
|
||||
#include "llvm/Support/MD5.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/Parallel.h"
|
||||
|
@ -30,45 +30,173 @@ ELF Improvements
|
||||
(`D107317 <https://reviews.llvm.org/D107317>`_)
|
||||
* ``--why-extract`` has been added to query why archive members/lazy object files are extracted.
|
||||
(`D109572 <https://reviews.llvm.org/D109572>`_)
|
||||
* ``e_entry`` no longer falls back to the address of ``.text`` if the entry symbol does not exist.
|
||||
Instead, a value of 0 will be written.
|
||||
(`D110014 <https://reviews.llvm.org/D110014>`_)
|
||||
* If ``-Map`` is specified, ``--cref`` will be printed to the specified file.
|
||||
(`D114663 <https://reviews.llvm.org/D114663>`_)
|
||||
* ``-z bti-report`` and ``-z cet-report`` are now supported.
|
||||
(`D113901 <https://reviews.llvm.org/D113901>`_)
|
||||
* ``--lto-pgo-warn-mismatch`` has been added.
|
||||
(`D104431 <https://reviews.llvm.org/D104431>`_)
|
||||
* Archives without an index (symbol table) are now supported and work with
|
||||
``--warn-backrefs``. One may build such an archive with ``llvm-ar rcS
|
||||
[--thin]`` to save space.
|
||||
(`D117284 <https://reviews.llvm.org/D117284>`_)
|
||||
The archive index may be `entirely ignored <https://reviews.llvm.org/D119074>`_
|
||||
in a future release.
|
||||
* No longer deduplicate local symbol names at the default optimization level of ``-O1``.
|
||||
This results in a larger ``.strtab`` (usually less than 1%) but a faster link
|
||||
time. Use optimization level ``-O2`` to restore the deduplication.
|
||||
time. Use optimization level ``-O2`` to restore the deduplication. The ``-O2``
|
||||
deduplication may be dropped in the future to help parallel ``.symtab`` write.
|
||||
* In relocatable output, relocations to discarded symbols now use tombstone
|
||||
values.
|
||||
(`D116946 <https://reviews.llvm.org/D116946>`_)
|
||||
* Orphan section placement now picks a more suitable segment. Previously the
|
||||
algorithm might pick a readonly segment for a writable orphan section and make
|
||||
the segment writable.
|
||||
(`D111717 <https://reviews.llvm.org/D111717>`_)
|
||||
* An empty output section moved by an ``INSERT`` comment now gets appropriate
|
||||
flags.
|
||||
(`D118529 <https://reviews.llvm.org/D118529>`_)
|
||||
* Negation in a memory region attribute is now correctly handled.
|
||||
(`D113771 <https://reviews.llvm.org/D113771>`_)
|
||||
* ``--compress-debug-sections=zlib`` is now run in parallel. ``{clang,gcc} -gz`` link
|
||||
actions are significantly faster.
|
||||
(`D117853 <https://reviews.llvm.org/D117853>`_)
|
||||
* "relocation out of range" diagnostics and a few uncommon diagnostics
|
||||
now report an object file location beside a source file location.
|
||||
(`D112518 <https://reviews.llvm.org/D117853>`_)
|
||||
* The write of ``.rela.dyn`` and ``SHF_MERGE|SHF_STRINGS`` sections (e.g.
|
||||
``.debug_str``) is now run in parallel.
|
||||
|
||||
Architecture specific changes:
|
||||
|
||||
* The AArch64 port now supports adrp+ldr and adrp+add optimizations.
|
||||
``--no-relax`` can suppress the optimization.
|
||||
(`D112063 <https://reviews.llvm.org/D112063>`_)
|
||||
(`D117614 <https://reviews.llvm.org/D117614>`_)
|
||||
* The x86-32 port now supports TLSDESC (``-mtls-dialect=gnu2``).
|
||||
(`D112582 <https://reviews.llvm.org/D112582>`_)
|
||||
* The x86-64 port now handles non-RAX/non-adjacent ``R_X86_64_GOTPC32_TLSDESC``
|
||||
and ``R_X86_64_TLSDESC_CALL`` (``-mtls-dialect=gnu2``).
|
||||
(`D114416 <https://reviews.llvm.org/D114416>`_)
|
||||
* The x86-32 and x86-64 ports now support mixed TLSDESC and TLS GD, i.e. mixing
|
||||
objects compiled with and without ``-mtls-dialect=gnu2`` referencing the same
|
||||
TLS variable is now supported.
|
||||
(`D114416 <https://reviews.llvm.org/D114416>`_)
|
||||
* For x86-64, ``--no-relax`` now suppresses ``R_X86_64_GOTPCRELX`` and
|
||||
``R_X86_64_REX_GOTPCRELX`` GOT optimization
|
||||
(`D113615 <https://reviews.llvm.org/D113615>`_)
|
||||
* ``R_X86_64_PLTOFF64`` is now supported.
|
||||
(`D112386 <https://reviews.llvm.org/D112386>`_)
|
||||
* ``R_AARCH64_NONE``, ``R_PPC_NONE``, and ``R_PPC64_NONE`` in input REL
|
||||
relocation sections are now supported.
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
|
||||
* ...
|
||||
* ``e_entry`` no longer falls back to the address of ``.text`` if the entry symbol does not exist.
|
||||
Instead, a value of 0 will be written.
|
||||
(`D110014 <https://reviews.llvm.org/D110014>`_)
|
||||
* ``--lto-pseudo-probe-for-profiling`` has been removed. In LTO, the compiler
|
||||
enables this feature automatically.
|
||||
(`D110209 <https://reviews.llvm.org/D110209>`_)
|
||||
* Use of ``--[no-]define-common``, ``-d``, ``-dc``, and ``-dp`` will now get a
|
||||
warning. They will be removed or ignored in 15.0.0.
|
||||
(`llvm-project#53660 <https://github.com/llvm/llvm-project/issues/53660>`_)
|
||||
|
||||
COFF Improvements
|
||||
-----------------
|
||||
|
||||
* ...
|
||||
* Correctly handle a signed immediate offset in ARM64 adr/adrp relocations.
|
||||
(`D114347 <https://reviews.llvm.org/D114347>`_)
|
||||
|
||||
* Omit section and label symbols from the symbol table.
|
||||
(`D113866 <https://reviews.llvm.org/D113866>`_)
|
||||
|
||||
MinGW Improvements
|
||||
------------------
|
||||
|
||||
* ...
|
||||
* ``--heap`` is now handled.
|
||||
(`D118405 <https://reviews.llvm.org/D118405>`_)
|
||||
|
||||
MachO Improvements
|
||||
------------------
|
||||
Mach-O Improvements
|
||||
-------------------
|
||||
|
||||
* Item 1.
|
||||
* The ``ld64.lld.darwinnew`` symlink has been removed. Use ``ld64.lld`` to
|
||||
invoke the Mach-O backend from now on. Moreover, the symlink
|
||||
``ld64.lld.darwinold`` -- and the old Mach-O LLD code that it pointed to --
|
||||
have been removed. (`D114842 <https://reviews.llvm.org/D114842>`_)
|
||||
* The "cannot export hidden symbol" error has been downgraded to a warning.
|
||||
(`D107011 <https://reviews.llvm.org/D107011>`_)
|
||||
* Common bitcode symbols are now supported.
|
||||
(`D107027 <https://reviews.llvm.org/D107027>`_)
|
||||
* Weak references in bitcode are now supported.
|
||||
(`D115949 <https://reviews.llvm.org/D115949>`_)
|
||||
* Thunk insertion now works more reliably.
|
||||
(`D108897 <https://reviews.llvm.org/D108897>`_,
|
||||
`D108924 <https://reviews.llvm.org/D108924>`_,
|
||||
`D109079 <https://reviews.llvm.org/D109079>`_,
|
||||
`D116705 <https://reviews.llvm.org/D116705>`_)
|
||||
* ``-ObjC`` now loads archive members before the symbol resolution phase.
|
||||
(`D108781 <https://reviews.llvm.org/D108781>`_)
|
||||
* ``-oso_prefix`` is now supported.
|
||||
(`D112291 <https://reviews.llvm.org/D112291>`_)
|
||||
* Properly encode binaries with zero exported symbols. Tools like
|
||||
``codesign_allocate`` no longer choke on those binaries.
|
||||
(`D112589 <https://reviews.llvm.org/D112589>`_)
|
||||
* We no longer treat architecture mismatches as a fatal error. Use
|
||||
``-arch_errors_fatal`` if that behavior is still desired.
|
||||
(`D113082 <https://reviews.llvm.org/D113082>`_)
|
||||
* Several performance improvements were done to speed LLD up on projects with
|
||||
a lot of framework flags and library lookups. Large Swift-based projects
|
||||
will benefit significantly.
|
||||
(`D113073 <https://reviews.llvm.org/D113073>`_,
|
||||
`D113063 <https://reviews.llvm.org/D113063>`_,
|
||||
`D113153 <https://reviews.llvm.org/D113153>`_,
|
||||
`D113235 <https://reviews.llvm.org/D113235>`_)
|
||||
* Several memory-reduction optimizations were done to reduce LLD's RSS
|
||||
footprint.
|
||||
(`D113813 <https://reviews.llvm.org/D113813>`_,
|
||||
`D113818 <https://reviews.llvm.org/D113818>`_)
|
||||
* Symbol patterns from ``-[un]exported_symbols_list`` are now processed in
|
||||
parallel. (`D113820 <https://reviews.llvm.org/D113820>`_)
|
||||
* ``.weak_def_can_be_hidden`` symbols can now be exported.
|
||||
(`D113167 <https://reviews.llvm.org/D113167>`_)
|
||||
* ``-S`` -- to omit debug info -- is now handled.
|
||||
(`D112594 <https://reviews.llvm.org/D112594>`_)
|
||||
* ``-v`` now writes to stderr instead of stdout.
|
||||
(`D113020 <https://reviews.llvm.org/D113020>`_)
|
||||
* Private externs with GOT relocations are now marked as LOCAL in the indirect
|
||||
symbol table. This allows ``strip -x`` to remove more symbols.
|
||||
(`D111852 <https://reviews.llvm.org/D111852>`_)
|
||||
* We no longer generate bogus addresses when ``__TEXT,__gcc_except_tab`` is
|
||||
renamed. (`D113582 <https://reviews.llvm.org/D113582>`_)
|
||||
* Unreferenced weak dylib symbols no longer trigger fetches from an archive.
|
||||
(`D115092 <https://reviews.llvm.org/D115092>`_)
|
||||
* ``$ld$hide`` symbols are now supported.
|
||||
(`D115775 <https://reviews.llvm.org/D115775>`_)
|
||||
* Symbols imported via ``-weak_framework`` are now properly marked as weak refs.
|
||||
(`D114397 <https://reviews.llvm.org/D114397>`_)
|
||||
* ``--warn-dylib-install-name`` and ``--no-warn-dylib-install-name`` were added
|
||||
to toggle LLD-specific warnings around the use of ``-install_name``.
|
||||
(`D113534 <https://reviews.llvm.org/D113534>`_)
|
||||
* Passing both ``--icf=all`` and ``-no_deduplicate`` no longer results in a
|
||||
warning. (`D110672 <https://reviews.llvm.org/D110672>`_)
|
||||
* ICF now deduplicates functions with (identical) unwind info too.
|
||||
(`D109946 <https://reviews.llvm.org/D109946>`_)
|
||||
* We now support ordering sections based on call graph profile data.
|
||||
(`D112164 <https://reviews.llvm.org/D112164>`_)
|
||||
* Map file output now proceeds in parallel with output of the binary.
|
||||
(`D117069 <https://reviews.llvm.org/D117069>`_)
|
||||
* The map file now contains dead-stripped symbols too.
|
||||
(`D114737 <https://reviews.llvm.org/D114737>`_)
|
||||
* Multiple TLV sections with different alignments are now handled properly.
|
||||
(`D116263 <https://reviews.llvm.org/D116263>`_)
|
||||
* ``--start-lib`` and ``--end-lib`` are now supported.
|
||||
(`D116913 <https://reviews.llvm.org/D116913>`_)
|
||||
* ``-noall_load`` is now supported.
|
||||
(`D117629 <https://reviews.llvm.org/D117629>`_)
|
||||
* ``-add_empty_section`` is now supported.
|
||||
(`D117749 <https://reviews.llvm.org/D117749>`_)
|
||||
|
||||
WebAssembly Improvements
|
||||
------------------------
|
||||
|
@ -226,10 +226,9 @@ class Mangled {
|
||||
/// Function signature for filtering mangled names.
|
||||
using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme);
|
||||
|
||||
/// Trigger explicit demangling to obtain rich mangling information. This is
|
||||
/// optimized for batch processing while populating a name index. To get the
|
||||
/// pure demangled name string for a single entity, use GetDemangledName()
|
||||
/// instead.
|
||||
/// Get rich mangling information. This is optimized for batch processing
|
||||
/// while populating a name index. To get the pure demangled name string for
|
||||
/// a single entity, use GetDemangledName() instead.
|
||||
///
|
||||
/// For names that match the Itanium mangling scheme, this uses LLVM's
|
||||
/// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
|
||||
@ -248,8 +247,8 @@ class Mangled {
|
||||
///
|
||||
/// \return
|
||||
/// True on success, false otherwise.
|
||||
bool DemangleWithRichManglingInfo(RichManglingContext &context,
|
||||
SkipMangledNameFn *skip_mangled_name);
|
||||
bool GetRichManglingInfo(RichManglingContext &context,
|
||||
SkipMangledNameFn *skip_mangled_name);
|
||||
|
||||
/// Try to identify the mangling scheme used.
|
||||
/// \param[in] name
|
||||
|
@ -43,25 +43,15 @@ class RichManglingContext {
|
||||
bool IsCtorOrDtor() const;
|
||||
|
||||
/// Get the base name of a function. This doesn't include trailing template
|
||||
/// arguments, ie "a::b<int>" gives "b". The result will overwrite the
|
||||
/// internal buffer. It can be obtained via GetBufferRef().
|
||||
void ParseFunctionBaseName();
|
||||
/// arguments, ie "a::b<int>" gives "b".
|
||||
llvm::StringRef ParseFunctionBaseName();
|
||||
|
||||
/// Get the context name for a function. For "a::b::c", this function returns
|
||||
/// "a::b". The result will overwrite the internal buffer. It can be obtained
|
||||
/// via GetBufferRef().
|
||||
void ParseFunctionDeclContextName();
|
||||
/// "a::b".
|
||||
llvm::StringRef ParseFunctionDeclContextName();
|
||||
|
||||
/// Get the entire demangled name. The result will overwrite the internal
|
||||
/// buffer. It can be obtained via GetBufferRef().
|
||||
void ParseFullName();
|
||||
|
||||
/// Obtain a StringRef to the internal buffer that holds the result of the
|
||||
/// most recent ParseXy() operation. The next ParseXy() call invalidates it.
|
||||
llvm::StringRef GetBufferRef() const {
|
||||
assert(m_provider != None && "Initialize a provider first");
|
||||
return m_buffer;
|
||||
}
|
||||
/// Get the entire demangled name.
|
||||
llvm::StringRef ParseFullName();
|
||||
|
||||
private:
|
||||
enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage };
|
||||
@ -69,9 +59,6 @@ class RichManglingContext {
|
||||
/// Selects the rich mangling info provider.
|
||||
InfoProvider m_provider = None;
|
||||
|
||||
/// Reference to the buffer used for results of ParseXy() operations.
|
||||
llvm::StringRef m_buffer;
|
||||
|
||||
/// Members for ItaniumPartialDemangler
|
||||
llvm::ItaniumPartialDemangler m_ipd;
|
||||
/// Note: m_ipd_buf is a raw pointer due to being resized by realloc via
|
||||
@ -93,7 +80,7 @@ class RichManglingContext {
|
||||
void ResetProvider(InfoProvider new_provider);
|
||||
|
||||
/// Uniform handling of string buffers for ItaniumPartialDemangler.
|
||||
void processIPDStrResult(char *ipd_res, size_t res_len);
|
||||
llvm::StringRef processIPDStrResult(char *ipd_res, size_t res_len);
|
||||
|
||||
/// Cast the given parser to the given type. Ideally we would have a type
|
||||
/// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we
|
||||
|
@ -1759,7 +1759,7 @@ class Process : public std::enable_shared_from_this<Process>,
|
||||
///
|
||||
/// If load_addr is within the address space the process has mapped
|
||||
/// range_info will be filled in with the start and end of that range as
|
||||
/// well as the permissions for that range and range_info.GetMapped will
|
||||
/// well as the permissions for that range and range_info. GetMapped will
|
||||
/// return true.
|
||||
///
|
||||
/// If load_addr is outside any mapped region then range_info will have its
|
||||
@ -1768,23 +1768,21 @@ class Process : public std::enable_shared_from_this<Process>,
|
||||
/// there are no valid mapped ranges between load_addr and the end of the
|
||||
/// process address space.
|
||||
///
|
||||
/// GetMemoryRegionInfo will only return an error if it is unimplemented for
|
||||
/// the current process.
|
||||
/// GetMemoryRegionInfo calls DoGetMemoryRegionInfo. Override that function in
|
||||
/// process subclasses.
|
||||
///
|
||||
/// \param[in] load_addr
|
||||
/// The load address to query the range_info for.
|
||||
/// The load address to query the range_info for. May include non
|
||||
/// address bits, these will be removed by the the ABI plugin if there is
|
||||
/// one.
|
||||
///
|
||||
/// \param[out] range_info
|
||||
/// An range_info value containing the details of the range.
|
||||
///
|
||||
/// \return
|
||||
/// An error value.
|
||||
virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
|
||||
MemoryRegionInfo &range_info) {
|
||||
Status error;
|
||||
error.SetErrorString("Process::GetMemoryRegionInfo() not supported");
|
||||
return error;
|
||||
}
|
||||
Status GetMemoryRegionInfo(lldb::addr_t load_addr,
|
||||
MemoryRegionInfo &range_info);
|
||||
|
||||
/// Obtain all the mapped memory regions within this process.
|
||||
///
|
||||
@ -2604,6 +2602,26 @@ void PruneThreadPlans();
|
||||
virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
|
||||
Status &error) = 0;
|
||||
|
||||
/// DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has
|
||||
/// removed non address bits from load_addr. Override this method in
|
||||
/// subclasses of Process.
|
||||
///
|
||||
/// See GetMemoryRegionInfo for details of the logic.
|
||||
///
|
||||
/// \param[in] load_addr
|
||||
/// The load address to query the range_info for. (non address bits
|
||||
/// removed)
|
||||
///
|
||||
/// \param[out] range_info
|
||||
/// An range_info value containing the details of the range.
|
||||
///
|
||||
/// \return
|
||||
/// An error value.
|
||||
virtual Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
|
||||
MemoryRegionInfo &range_info) {
|
||||
return Status("Process::DoGetMemoryRegionInfo() not supported");
|
||||
}
|
||||
|
||||
lldb::StateType GetPrivateState();
|
||||
|
||||
/// The "private" side of resuming a process. This doesn't alter the state
|
||||
|
@ -1665,14 +1665,11 @@ class CommandObjectMemoryRegion : public CommandObjectParsed {
|
||||
m_prev_end_addr = LLDB_INVALID_ADDRESS;
|
||||
|
||||
const size_t argc = command.GetArgumentCount();
|
||||
if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS)) {
|
||||
result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n",
|
||||
m_cmd_name.c_str(), m_cmd_syntax.c_str());
|
||||
return false;
|
||||
}
|
||||
const lldb::ABISP &abi = process_sp->GetABI();
|
||||
|
||||
if (argc == 1) {
|
||||
auto load_addr_str = command[0].ref();
|
||||
// Non-address bits in this will be handled later by GetMemoryRegion
|
||||
load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
|
||||
LLDB_INVALID_ADDRESS, &error);
|
||||
if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) {
|
||||
@ -1680,6 +1677,19 @@ class CommandObjectMemoryRegion : public CommandObjectParsed {
|
||||
command[0].c_str(), error.AsCString());
|
||||
return false;
|
||||
}
|
||||
} else if (argc > 1 ||
|
||||
// When we're repeating the command, the previous end address is
|
||||
// used for load_addr. If that was 0xF...F then we must have
|
||||
// reached the end of memory.
|
||||
(argc == 0 && load_addr == LLDB_INVALID_ADDRESS) ||
|
||||
// If the target has non-address bits (tags, limited virtual
|
||||
// address size, etc.), the end of mappable memory will be lower
|
||||
// than that. So if we find any non-address bit set, we must be
|
||||
// at the end of the mappable range.
|
||||
(abi && (abi->FixDataAddress(load_addr) != load_addr))) {
|
||||
result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n",
|
||||
m_cmd_name.c_str(), m_cmd_syntax.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
lldb_private::MemoryRegionInfo range_info;
|
||||
|
@ -1320,6 +1320,53 @@ class CommandObjectThreadException : public CommandObjectIterateOverThreads {
|
||||
}
|
||||
};
|
||||
|
||||
class CommandObjectThreadSiginfo : public CommandObjectIterateOverThreads {
|
||||
public:
|
||||
CommandObjectThreadSiginfo(CommandInterpreter &interpreter)
|
||||
: CommandObjectIterateOverThreads(
|
||||
interpreter, "thread siginfo",
|
||||
"Display the current siginfo object for a thread. Defaults to "
|
||||
"the current thread.",
|
||||
"thread siginfo",
|
||||
eCommandRequiresProcess | eCommandTryTargetAPILock |
|
||||
eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
|
||||
|
||||
~CommandObjectThreadSiginfo() override = default;
|
||||
|
||||
void
|
||||
HandleArgumentCompletion(CompletionRequest &request,
|
||||
OptionElementVector &opt_element_vector) override {
|
||||
CommandCompletions::InvokeCommonCompletionCallbacks(
|
||||
GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
|
||||
request, nullptr);
|
||||
}
|
||||
|
||||
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
|
||||
ThreadSP thread_sp =
|
||||
m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
|
||||
if (!thread_sp) {
|
||||
result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
|
||||
tid);
|
||||
return false;
|
||||
}
|
||||
|
||||
Stream &strm = result.GetOutputStream();
|
||||
if (!thread_sp->GetDescription(strm, eDescriptionLevelFull, false, false)) {
|
||||
result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
|
||||
thread_sp->GetIndexID());
|
||||
return false;
|
||||
}
|
||||
ValueObjectSP exception_object_sp = thread_sp->GetSiginfoValue();
|
||||
if (exception_object_sp)
|
||||
exception_object_sp->Dump(strm);
|
||||
else
|
||||
strm.Printf("(no siginfo)\n");
|
||||
strm.PutChar('\n');
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// CommandObjectThreadReturn
|
||||
#define LLDB_OPTIONS_thread_return
|
||||
#include "CommandOptions.inc"
|
||||
@ -2293,6 +2340,8 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread(
|
||||
CommandObjectSP(new CommandObjectThreadInfo(interpreter)));
|
||||
LoadSubCommand("exception", CommandObjectSP(new CommandObjectThreadException(
|
||||
interpreter)));
|
||||
LoadSubCommand("siginfo",
|
||||
CommandObjectSP(new CommandObjectThreadSiginfo(interpreter)));
|
||||
LoadSubCommand("step-in",
|
||||
CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
|
||||
interpreter, "thread step-in",
|
||||
|
@ -195,8 +195,8 @@ static char *GetDLangDemangledStr(const char *M) {
|
||||
|
||||
// Explicit demangling for scheduled requests during batch processing. This
|
||||
// makes use of ItaniumPartialDemangler's rich demangle info
|
||||
bool Mangled::DemangleWithRichManglingInfo(
|
||||
RichManglingContext &context, SkipMangledNameFn *skip_mangled_name) {
|
||||
bool Mangled::GetRichManglingInfo(RichManglingContext &context,
|
||||
SkipMangledNameFn *skip_mangled_name) {
|
||||
// Others are not meant to arrive here. ObjC names or C's main() for example
|
||||
// have their names stored in m_demangled, while m_mangled is empty.
|
||||
assert(m_mangled);
|
||||
@ -214,25 +214,16 @@ bool Mangled::DemangleWithRichManglingInfo(
|
||||
case eManglingSchemeItanium:
|
||||
// We want the rich mangling info here, so we don't care whether or not
|
||||
// there is a demangled string in the pool already.
|
||||
if (context.FromItaniumName(m_mangled)) {
|
||||
// If we got an info, we have a name. Copy to string pool and connect the
|
||||
// counterparts to accelerate later access in GetDemangledName().
|
||||
context.ParseFullName();
|
||||
m_demangled.SetStringWithMangledCounterpart(context.GetBufferRef(),
|
||||
m_mangled);
|
||||
return true;
|
||||
} else {
|
||||
m_demangled.SetCString("");
|
||||
return false;
|
||||
}
|
||||
return context.FromItaniumName(m_mangled);
|
||||
|
||||
case eManglingSchemeMSVC: {
|
||||
// We have no rich mangling for MSVC-mangled names yet, so first try to
|
||||
// demangle it if necessary.
|
||||
if (!m_demangled && !m_mangled.GetMangledCounterpart(m_demangled)) {
|
||||
if (char *d = GetMSVCDemangledStr(m_mangled.GetCString())) {
|
||||
// If we got an info, we have a name. Copy to string pool and connect
|
||||
// the counterparts to accelerate later access in GetDemangledName().
|
||||
// Without the rich mangling info we have to demangle the full name.
|
||||
// Copy it to string pool and connect the counterparts to accelerate
|
||||
// later access in GetDemangledName().
|
||||
m_demangled.SetStringWithMangledCounterpart(llvm::StringRef(d),
|
||||
m_mangled);
|
||||
::free(d);
|
||||
|
@ -83,15 +83,15 @@ bool RichManglingContext::IsCtorOrDtor() const {
|
||||
llvm_unreachable("Fully covered switch above!");
|
||||
}
|
||||
|
||||
void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) {
|
||||
llvm::StringRef RichManglingContext::processIPDStrResult(char *ipd_res,
|
||||
size_t res_size) {
|
||||
// Error case: Clear the buffer.
|
||||
if (LLVM_UNLIKELY(ipd_res == nullptr)) {
|
||||
assert(res_size == m_ipd_buf_size &&
|
||||
"Failed IPD queries keep the original size in the N parameter");
|
||||
|
||||
m_ipd_buf[0] = '\0';
|
||||
m_buffer = llvm::StringRef(m_ipd_buf, 0);
|
||||
return;
|
||||
return llvm::StringRef(m_ipd_buf, 0);
|
||||
}
|
||||
|
||||
// IPD's res_size includes null terminator.
|
||||
@ -109,60 +109,54 @@ void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) {
|
||||
}
|
||||
|
||||
// 99% case: Just remember the string length.
|
||||
m_buffer = llvm::StringRef(m_ipd_buf, res_size - 1);
|
||||
return llvm::StringRef(m_ipd_buf, res_size - 1);
|
||||
}
|
||||
|
||||
void RichManglingContext::ParseFunctionBaseName() {
|
||||
llvm::StringRef RichManglingContext::ParseFunctionBaseName() {
|
||||
assert(m_provider != None && "Initialize a provider first");
|
||||
switch (m_provider) {
|
||||
case ItaniumPartialDemangler: {
|
||||
auto n = m_ipd_buf_size;
|
||||
auto buf = m_ipd.getFunctionBaseName(m_ipd_buf, &n);
|
||||
processIPDStrResult(buf, n);
|
||||
return;
|
||||
return processIPDStrResult(buf, n);
|
||||
}
|
||||
case PluginCxxLanguage:
|
||||
m_buffer =
|
||||
get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetBasename();
|
||||
return;
|
||||
return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
|
||||
->GetBasename();
|
||||
case None:
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
void RichManglingContext::ParseFunctionDeclContextName() {
|
||||
llvm::StringRef RichManglingContext::ParseFunctionDeclContextName() {
|
||||
assert(m_provider != None && "Initialize a provider first");
|
||||
switch (m_provider) {
|
||||
case ItaniumPartialDemangler: {
|
||||
auto n = m_ipd_buf_size;
|
||||
auto buf = m_ipd.getFunctionDeclContextName(m_ipd_buf, &n);
|
||||
processIPDStrResult(buf, n);
|
||||
return;
|
||||
return processIPDStrResult(buf, n);
|
||||
}
|
||||
case PluginCxxLanguage:
|
||||
m_buffer =
|
||||
get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetContext();
|
||||
return;
|
||||
return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
|
||||
->GetContext();
|
||||
case None:
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
void RichManglingContext::ParseFullName() {
|
||||
llvm::StringRef RichManglingContext::ParseFullName() {
|
||||
assert(m_provider != None && "Initialize a provider first");
|
||||
switch (m_provider) {
|
||||
case ItaniumPartialDemangler: {
|
||||
auto n = m_ipd_buf_size;
|
||||
auto buf = m_ipd.finishDemangle(m_ipd_buf, &n);
|
||||
processIPDStrResult(buf, n);
|
||||
return;
|
||||
return processIPDStrResult(buf, n);
|
||||
}
|
||||
case PluginCxxLanguage:
|
||||
m_buffer = get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
|
||||
->GetFullName()
|
||||
.GetStringRef();
|
||||
return;
|
||||
return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
|
||||
->GetFullName()
|
||||
.GetStringRef();
|
||||
case None:
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ void InstrumentationRuntimeASan::Activate() {
|
||||
if (!process_sp)
|
||||
return;
|
||||
|
||||
ConstString symbol_name("__asan::AsanDie()");
|
||||
ConstString symbol_name("_ZN6__asanL7AsanDieEv");
|
||||
const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType(
|
||||
symbol_name, eSymbolTypeCode);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user