aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-03-31 20:49:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-03-31 20:49:22 +0000
commit11ee15ea4ee1ea5555f8d7ba1ec5ffe956df2a8c (patch)
treedf70bd53f42f50adc3a1fa830f6aec7bfa533c06
parent11edbfca22fe6e8280caeb77832f4dfbb68ed274 (diff)
Vendor import of llvm-project branch release/16.x llvmorg-16.0.0-0-g08d094a0e457 (aka 16.0.0 release).vendor/llvm-project/llvmorg-16.0.0-0-g08d094a0e457
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--clang/include/clang/Lex/Preprocessor.h184
-rw-r--r--clang/include/clang/Sema/Sema.h8
-rw-r--r--clang/include/clang/Sema/SemaInternal.h4
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h4
-rw-r--r--clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h6
-rw-r--r--clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h27
-rw-r--r--clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h6
-rw-r--r--clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h29
-rw-r--r--clang/lib/AST/ExprConstant.cpp2
-rw-r--r--clang/lib/AST/Type.cpp12
-rw-r--r--clang/lib/Basic/Targets/PPC.h5
-rw-r--r--clang/lib/CodeGen/CGCXXABI.h5
-rw-r--r--clang/lib/CodeGen/CGCall.cpp4
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp11
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp21
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp4
-rw-r--r--clang/lib/Driver/Driver.cpp4
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp4
-rw-r--r--clang/lib/Driver/ToolChains/Arch/PPC.cpp93
-rw-r--r--clang/lib/Driver/ToolChains/Arch/PPC.h2
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp11
-rw-r--r--clang/lib/Driver/ToolChains/Cuda.cpp7
-rw-r--r--clang/lib/Driver/ToolChains/FreeBSD.cpp45
-rw-r--r--clang/lib/Driver/ToolChains/FreeBSD.h12
-rw-r--r--clang/lib/Driver/ToolChains/Fuchsia.cpp2
-rw-r--r--clang/lib/Format/IntegerLiteralSeparatorFixer.cpp7
-rw-r--r--clang/lib/Format/QualifierAlignmentFixer.cpp5
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp11
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp9
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp37
-rw-r--r--clang/lib/Lex/Preprocessor.cpp44
-rw-r--r--clang/lib/Lex/TokenLexer.cpp12
-rw-r--r--clang/lib/Sema/SemaAttr.cpp17
-rw-r--r--clang/lib/Sema/SemaModule.cpp13
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp7
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp234
-rw-r--r--clang/lib/Sema/TreeTransform.h3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporter.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp13
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp150
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp4
-rw-r--r--clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp33
-rw-r--r--compiler-rt/lib/builtins/cpu_model.c3
-rw-r--r--libcxx/include/__algorithm/ranges_binary_search.h4
-rw-r--r--libcxx/include/__config8
-rw-r--r--libcxx/include/__format/concepts.h5
-rw-r--r--libcxx/include/__format/formatter_floating_point.h3
-rw-r--r--libcxx/include/__functional/function.h38
-rw-r--r--libcxx/include/__memory/construct_at.h10
-rw-r--r--libcxx/include/__memory/shared_ptr.h218
-rw-r--r--libcxx/include/__memory/uninitialized_algorithms.h26
-rw-r--r--libcxx/include/__ranges/elements_view.h118
-rw-r--r--libcxx/include/__ranges/filter_view.h50
-rw-r--r--libcxx/include/__ranges/iota_view.h432
-rw-r--r--libcxx/include/__ranges/istream_view.h26
-rw-r--r--libcxx/include/__ranges/join_view.h89
-rw-r--r--libcxx/include/__ranges/split_view.h52
-rw-r--r--libcxx/include/__ranges/take_while_view.h30
-rw-r--r--libcxx/include/__ranges/transform_view.h127
-rw-r--r--libcxx/include/__type_traits/add_pointer.h4
-rw-r--r--libcxx/include/__type_traits/remove_pointer.h4
-rw-r--r--libcxx/include/any10
-rw-r--r--libcxx/include/version2
-rw-r--r--lld/ELF/Arch/RISCV.cpp6
-rw-r--r--lld/ELF/ICF.cpp10
-rw-r--r--lld/ELF/SymbolTable.cpp4
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp164
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/Coroutines.h7
-rw-r--r--llvm/include/llvm/Analysis/ScalarEvolution.h11
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h1
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVStringPool.h7
-rw-r--r--llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h4
-rw-r--r--llvm/include/llvm/Support/ExitCodes.h6
-rw-r--r--llvm/include/llvm/Support/RISCVISAInfo.h6
-rw-r--r--llvm/include/llvm/Support/Signals.h11
-rw-r--r--llvm/include/llvm/TargetParser/RISCVTargetParser.h5
-rw-r--r--llvm/include/llvm/TargetParser/Triple.h8
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp13
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp6
-rw-r--r--llvm/lib/CodeGen/TargetLoweringBase.cpp4
-rw-r--r--llvm/lib/DebugInfo/LogicalView/Core/LVSupport.cpp6
-rw-r--r--llvm/lib/DebugInfo/Symbolize/Symbolize.cpp27
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_unix.S2
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_gnu.S2
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_msvc.asm12
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_unix.S2
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_gnu.S2
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_msvc.asm36
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_impl.h10
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_unix.S2
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_gnu.S2
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_msvc.asm36
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_unix.S2
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_gnu.S2
-rw-r--r--llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_msvc.asm36
-rw-r--r--llvm/lib/Support/BLAKE3/llvm_blake3_prefix.h41
-rw-r--r--llvm/lib/Support/RISCVISAInfo.cpp61
-rw-r--r--llvm/lib/Support/Windows/Path.inc2
-rw-r--r--llvm/lib/Support/Windows/Signals.inc23
-rw-r--r--llvm/lib/Support/Z3Solver.cpp2
-rw-r--r--llvm/lib/Support/raw_ostream.cpp10
-rw-r--r--llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp2
-rw-r--r--llvm/lib/Target/PowerPC/PPCTargetMachine.cpp5
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp19
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.h4
-rw-r--r--llvm/lib/Target/RISCV/RISCVSubtarget.cpp3
-rw-r--r--llvm/lib/Target/RISCV/RISCVSubtarget.h2
-rw-r--r--llvm/lib/Target/X86/X86ISelDAGToDAG.cpp5
-rw-r--r--llvm/lib/TargetParser/RISCVTargetParser.cpp6
-rw-r--r--llvm/lib/Transforms/IPO/Attributor.cpp22
-rw-r--r--llvm/lib/Transforms/Vectorize/LoopVectorize.cpp15
-rw-r--r--llvm/tools/llvm-cov/CodeCoverage.cpp2
-rw-r--r--openmp/runtime/src/kmp_os.h2
-rw-r--r--openmp/runtime/src/kmp_runtime.cpp6
-rw-r--r--openmp/runtime/src/kmp_safe_c_api.h2
-rw-r--r--openmp/runtime/src/kmp_str.cpp8
-rw-r--r--openmp/runtime/src/z_Linux_asm.S5
120 files changed, 1808 insertions, 1271 deletions
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 23752823e88f..652c15afcce8 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4559,6 +4559,8 @@ def mnvs : Flag<["-"], "mnvs">, Group<m_hexagon_Features_Group>,
Flags<[CC1Option]>, HelpText<"Enable generation of new-value stores">;
def mno_nvs : Flag<["-"], "mno-nvs">, Group<m_hexagon_Features_Group>,
Flags<[CC1Option]>, HelpText<"Disable generation of new-value stores">;
+def mcabac: Flag<["-"], "mcabac">, Group<m_hexagon_Features_Group>,
+ HelpText<"Enable CABAC instructions">;
// SPARC feature flags
def mfpu : Flag<["-"], "mfpu">, Group<m_sparc_Features_Group>;
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index f383a2e5b530..322626802eab 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -193,11 +193,6 @@ class Preprocessor {
LangOptions::FPEvalMethodKind CurrentFPEvalMethod =
LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
- // Keeps the value of the last evaluation method before a
- // `pragma float_control (precise,off) is applied.
- LangOptions::FPEvalMethodKind LastFPEvalMethod =
- LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
-
// The most recent pragma location where the floating point evaluation
// method was modified. This is used to determine whether the
// 'pragma clang fp eval_method' was used whithin the current scope.
@@ -313,6 +308,9 @@ private:
/// The import path for named module that we're currently processing.
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> NamedModuleImportPath;
+ /// Whether the import is an `@import` or a standard c++ modules import.
+ bool IsAtImport = false;
+
/// Whether the last token we lexed was an '@'.
bool LastTokenWasAt = false;
@@ -456,6 +454,144 @@ private:
TrackGMF TrackGMFState = TrackGMF::BeforeGMFIntroducer;
+ /// Track the status of the c++20 module decl.
+ ///
+ /// module-declaration:
+ /// 'export'[opt] 'module' module-name module-partition[opt]
+ /// attribute-specifier-seq[opt] ';'
+ ///
+ /// module-name:
+ /// module-name-qualifier[opt] identifier
+ ///
+ /// module-partition:
+ /// ':' module-name-qualifier[opt] identifier
+ ///
+ /// module-name-qualifier:
+ /// identifier '.'
+ /// module-name-qualifier identifier '.'
+ ///
+ /// Transition state:
+ ///
+ /// NotAModuleDecl --- export ---> FoundExport
+ /// NotAModuleDecl --- module ---> ImplementationCandidate
+ /// FoundExport --- module ---> InterfaceCandidate
+ /// ImplementationCandidate --- Identifier ---> ImplementationCandidate
+ /// ImplementationCandidate --- period ---> ImplementationCandidate
+ /// ImplementationCandidate --- colon ---> ImplementationCandidate
+ /// InterfaceCandidate --- Identifier ---> InterfaceCandidate
+ /// InterfaceCandidate --- period ---> InterfaceCandidate
+ /// InterfaceCandidate --- colon ---> InterfaceCandidate
+ /// ImplementationCandidate --- Semi ---> NamedModuleImplementation
+ /// NamedModuleInterface --- Semi ---> NamedModuleInterface
+ /// NamedModuleImplementation --- Anything ---> NamedModuleImplementation
+ /// NamedModuleInterface --- Anything ---> NamedModuleInterface
+ ///
+ /// FIXME: We haven't handle attribute-specifier-seq here. It may not be bad
+ /// soon since we don't support any module attributes yet.
+ class ModuleDeclSeq {
+ enum ModuleDeclState : int {
+ NotAModuleDecl,
+ FoundExport,
+ InterfaceCandidate,
+ ImplementationCandidate,
+ NamedModuleInterface,
+ NamedModuleImplementation,
+ };
+
+ public:
+ ModuleDeclSeq() : State(NotAModuleDecl) {}
+
+ void handleExport() {
+ if (State == NotAModuleDecl)
+ State = FoundExport;
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handleModule() {
+ if (State == FoundExport)
+ State = InterfaceCandidate;
+ else if (State == NotAModuleDecl)
+ State = ImplementationCandidate;
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handleIdentifier(IdentifierInfo *Identifier) {
+ if (isModuleCandidate() && Identifier)
+ Name += Identifier->getName().str();
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handleColon() {
+ if (isModuleCandidate())
+ Name += ":";
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handlePeriod() {
+ if (isModuleCandidate())
+ Name += ".";
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handleSemi() {
+ if (!Name.empty() && isModuleCandidate()) {
+ if (State == InterfaceCandidate)
+ State = NamedModuleInterface;
+ else if (State == ImplementationCandidate)
+ State = NamedModuleImplementation;
+ else
+ llvm_unreachable("Unimaged ModuleDeclState.");
+ } else if (!isNamedModule())
+ reset();
+ }
+
+ void handleMisc() {
+ if (!isNamedModule())
+ reset();
+ }
+
+ bool isModuleCandidate() const {
+ return State == InterfaceCandidate || State == ImplementationCandidate;
+ }
+
+ bool isNamedModule() const {
+ return State == NamedModuleInterface ||
+ State == NamedModuleImplementation;
+ }
+
+ bool isNamedInterface() const { return State == NamedModuleInterface; }
+
+ bool isImplementationUnit() const {
+ return State == NamedModuleImplementation && !getName().contains(':');
+ }
+
+ StringRef getName() const {
+ assert(isNamedModule() && "Can't get name from a non named module");
+ return Name;
+ }
+
+ StringRef getPrimaryName() const {
+ assert(isNamedModule() && "Can't get name from a non named module");
+ return getName().split(':').first;
+ }
+
+ void reset() {
+ Name.clear();
+ State = NotAModuleDecl;
+ }
+
+ private:
+ ModuleDeclState State;
+ std::string Name;
+ };
+
+ ModuleDeclSeq ModuleDeclState;
+
/// Whether the module import expects an identifier next. Otherwise,
/// it expects a '.' or ';'.
bool ModuleImportExpectsIdentifier = false;
@@ -2194,14 +2330,6 @@ public:
return LastFPEvalPragmaLocation;
}
- LangOptions::FPEvalMethodKind getLastFPEvalMethod() const {
- return LastFPEvalMethod;
- }
-
- void setLastFPEvalMethod(LangOptions::FPEvalMethodKind Val) {
- LastFPEvalMethod = Val;
- }
-
void setCurrentFPEvalMethod(SourceLocation PragmaLoc,
LangOptions::FPEvalMethodKind Val) {
assert(Val != LangOptions::FEM_UnsetOnCommandLine &&
@@ -2225,6 +2353,36 @@ public:
/// Retrieves the module whose implementation we're current compiling, if any.
Module *getCurrentModuleImplementation();
+ /// If we are preprocessing a named module.
+ bool isInNamedModule() const { return ModuleDeclState.isNamedModule(); }
+
+ /// If we are proprocessing a named interface unit.
+ /// Note that a module implementation partition is not considered as an
+ /// named interface unit here although it is importable
+ /// to ease the parsing.
+ bool isInNamedInterfaceUnit() const {
+ return ModuleDeclState.isNamedInterface();
+ }
+
+ /// Get the named module name we're preprocessing.
+ /// Requires we're preprocessing a named module.
+ StringRef getNamedModuleName() const { return ModuleDeclState.getName(); }
+
+ /// If we are implementing an implementation module unit.
+ /// Note that the module implementation partition is not considered as an
+ /// implementation unit.
+ bool isInImplementationUnit() const {
+ return ModuleDeclState.isImplementationUnit();
+ }
+
+ /// If we're importing a standard C++20 Named Modules.
+ bool isInImportingCXXNamedModules() const {
+ // NamedModuleImportPath will be non-empty only if we're importing
+ // Standard C++ named modules.
+ return !NamedModuleImportPath.empty() && getLangOpts().CPlusPlusModules &&
+ !IsAtImport;
+ }
+
/// Allocate a new MacroInfo object with the provided SourceLocation.
MacroInfo *AllocateMacroInfo(SourceLocation L);
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 66b018d8fba1..d40dacb5aa0f 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -238,11 +238,9 @@ namespace threadSafety {
// FIXME: No way to easily map from TemplateTypeParmTypes to
// TemplateTypeParmDecls, so we have this horrible PointerUnion.
-using UnexpandedParameterPack = std::pair<
- llvm::PointerUnion<
- const TemplateTypeParmType *, const SubstTemplateTypeParmPackType *,
- const SubstNonTypeTemplateParmPackExpr *, const NamedDecl *>,
- SourceLocation>;
+typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType *, NamedDecl *>,
+ SourceLocation>
+ UnexpandedParameterPack;
/// Describes whether we've seen any nullability information for the given
/// file.
diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h
index 4eca50919dc7..842eec099540 100644
--- a/clang/include/clang/Sema/SemaInternal.h
+++ b/clang/include/clang/Sema/SemaInternal.h
@@ -62,7 +62,7 @@ inline InheritableAttr *getDLLAttr(Decl *D) {
}
/// Retrieve the depth and index of a template parameter.
-inline std::pair<unsigned, unsigned> getDepthAndIndex(const NamedDecl *ND) {
+inline std::pair<unsigned, unsigned> getDepthAndIndex(NamedDecl *ND) {
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
return std::make_pair(TTP->getDepth(), TTP->getIndex());
@@ -79,7 +79,7 @@ getDepthAndIndex(UnexpandedParameterPack UPP) {
if (const auto *TTP = UPP.first.dyn_cast<const TemplateTypeParmType *>())
return std::make_pair(TTP->getDepth(), TTP->getIndex());
- return getDepthAndIndex(UPP.first.get<const NamedDecl *>());
+ return getDepthAndIndex(UPP.first.get<NamedDecl *>());
}
class TypoCorrectionConsumer : public VisibleDeclConsumer {
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
index ea05b9f8ee3f..fcc9c02999b3 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
@@ -454,7 +454,9 @@ public:
llvm::SMTExprRef OperandExp =
getSymExpr(Solver, Ctx, USE->getOperand(), &OperandTy, hasComparison);
llvm::SMTExprRef UnaryExp =
- fromUnOp(Solver, USE->getOpcode(), OperandExp);
+ OperandTy->isRealFloatingType()
+ ? fromFloatUnOp(Solver, USE->getOpcode(), OperandExp)
+ : fromUnOp(Solver, USE->getOpcode(), OperandExp);
// Currently, without the `support-symbolic-integer-casts=true` option,
// we do not emit `SymbolCast`s for implicit casts.
diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
index a8cb15847b78..109cf049a652 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
@@ -35,9 +35,13 @@ enum class ScanningOutputFormat {
/// intermodule dependency information.
Make,
- /// This outputs the full module dependency graph suitable for use for
+ /// This outputs the full clang module dependency graph suitable for use for
/// explicitly building modules.
Full,
+
+ /// This outputs the dependency graph for standard c++ modules in P1689R5
+ /// format.
+ P1689,
};
/// The dependency scanning service contains shared configuration and state that
diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
index 6af878dbda95..b1a4df141edc 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
@@ -67,6 +67,12 @@ struct FullDependenciesResult {
std::vector<ModuleDeps> DiscoveredModules;
};
+struct P1689Rule {
+ std::string PrimaryOutput;
+ std::optional<P1689ModuleInfo> Provides;
+ std::vector<P1689ModuleInfo> Requires;
+};
+
/// The high-level implementation of the dependency discovery tool that runs on
/// an individual worker thread.
class DependencyScanningTool {
@@ -87,9 +93,24 @@ public:
getDependencyFile(const std::vector<std::string> &CommandLine, StringRef CWD,
std::optional<StringRef> ModuleName = std::nullopt);
- /// Collect the full module dependency graph for the input, ignoring any
- /// modules which have already been seen. If \p ModuleName isn't empty, this
- /// function returns the full dependency information of module \p ModuleName.
+ /// Collect the module dependency in P1689 format for C++20 named modules.
+ ///
+ /// \param MakeformatOutput The output parameter for dependency information
+ /// in make format if the command line requires to generate make-format
+ /// dependency information by `-MD -MF <dep_file>`.
+ ///
+ /// \param MakeformatOutputPath The output parameter for the path to
+ /// \param MakeformatOutput.
+ ///
+ /// \returns A \c StringError with the diagnostic output if clang errors
+ /// occurred, P1689 dependency format rules otherwise.
+ llvm::Expected<P1689Rule>
+ getP1689ModuleDependencyFile(
+ const clang::tooling::CompileCommand &Command, StringRef CWD,
+ std::string &MakeformatOutput, std::string &MakeformatOutputPath);
+
+ /// Given a Clang driver command-line for a translation unit, gather the
+ /// modular dependencies and return the information needed for explicit build.
///
/// \param AlreadySeen This stores modules which have previously been
/// reported. Use the same instance for all calls to this
diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
index 458c4d936c83..6edf2cbe6b53 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
@@ -41,7 +41,11 @@ class DependencyConsumer {
public:
virtual ~DependencyConsumer() {}
- virtual void handleBuildCommand(Command Cmd) = 0;
+ virtual void handleProvidedAndRequiredStdCXXModules(
+ std::optional<P1689ModuleInfo> Provided,
+ std::vector<P1689ModuleInfo> Requires) {}
+
+ virtual void handleBuildCommand(Command Cmd) {}
virtual void
handleDependencyOutputOpts(const DependencyOutputOptions &Opts) = 0;
diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
index 6e4cec25961d..bce3e066372f 100644
--- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
+++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
@@ -62,6 +62,27 @@ struct ModuleID {
}
};
+/// P1689ModuleInfo - Represents the needed information of standard C++20
+/// modules for P1689 format.
+struct P1689ModuleInfo {
+ /// The name of the module. This may include `:` for partitions.
+ std::string ModuleName;
+
+ /// Optional. The source path to the module.
+ std::string SourcePath;
+
+ /// If this module is a standard c++ interface unit.
+ bool IsStdCXXModuleInterface = true;
+
+ enum class ModuleType {
+ NamedCXXModule
+ // To be supported
+ // AngleHeaderUnit,
+ // QuoteHeaderUnit
+ };
+ ModuleType Type = ModuleType::NamedCXXModule;
+};
+
/// An output from a module compilation, such as the path of the module file.
enum class ModuleOutputKind {
/// The module file (.pcm). Required.
@@ -181,7 +202,7 @@ public:
ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts,
CompilerInstance &ScanInstance, DependencyConsumer &C,
CompilerInvocation OriginalCI, bool OptimizeArgs,
- bool EagerLoadModules);
+ bool EagerLoadModules, bool IsStdModuleP1689Format);
void attachToPreprocessor(Preprocessor &PP) override;
void attachToASTReader(ASTReader &R) override;
@@ -219,6 +240,12 @@ private:
bool OptimizeArgs;
/// Whether to set up command-lines to load PCM files eagerly.
bool EagerLoadModules;
+ /// If we're generating dependency output in P1689 format
+ /// for standard C++ modules.
+ bool IsStdModuleP1689Format;
+
+ std::optional<P1689ModuleInfo> ProvidedStdCXXModule;
+ std::vector<P1689ModuleInfo> RequiredStdCXXModules;
/// Checks whether the module is known as being prebuilt.
bool isPrebuiltModule(const Module *M);
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 912a210fd254..9c56ab12529c 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10913,7 +10913,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
for (unsigned I = OldElts; I < N; ++I)
Value->getArrayInitializedElt(I) = Filler;
- if (HasTrivialConstructor && N == FinalSize) {
+ if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
// If we have a trivial constructor, only evaluate it once and copy
// the result into all the array elements.
APValue &FirstResult = Value->getArrayInitializedElt(0);
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index a713d6e3bd03..54e62a1939f7 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2487,11 +2487,13 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
return true;
if (const auto *RT = CanonicalType->getAs<RecordType>()) {
if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- // C++11 [class]p6:
- // A trivial class is a class that has a default constructor,
- // has no non-trivial default constructors, and is trivially
- // copyable.
- return ClassDecl->hasDefaultConstructor() &&
+ // C++20 [class]p6:
+ // A trivial class is a class that is trivially copyable, and
+ // has one or more eligible default constructors such that each is
+ // trivial.
+ // FIXME: We should merge this definition of triviality into
+ // CXXRecordDecl::isTrivial. Currently it computes the wrong thing.
+ return ClassDecl->hasTrivialDefaultConstructor() &&
!ClassDecl->hasNonTrivialDefaultConstructor() &&
ClassDecl->isTriviallyCopyable();
}
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index cc185fdadfcb..c8197154fff7 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -428,7 +428,10 @@ public:
ABI = "elfv2";
} else {
DataLayout = "E-m:e-i64:64-n32:64";
- ABI = "elfv1";
+ if (Triple.isPPC64ELFv2ABI())
+ ABI = "elfv2";
+ else
+ ABI = "elfv1";
}
if (Triple.isOSFreeBSD() || Triple.isOSOpenBSD() || Triple.isMusl()) {
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index a600768b2074..78646996eac2 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -379,9 +379,8 @@ public:
/// zero if no specific type is applicable, e.g. if the ABI expects the "this"
/// parameter to point to some artificial offset in a complete object due to
/// vbases being reordered.
- virtual const CXXRecordDecl *
- getThisArgumentTypeForMethod(const CXXMethodDecl *MD) {
- return MD->getParent();
+ virtual const CXXRecordDecl *getThisArgumentTypeForMethod(GlobalDecl GD) {
+ return cast<CXXMethodDecl>(GD.getDecl())->getParent();
}
/// Perform ABI-specific "this" argument adjustment required prior to
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index dfa552161d7c..ee5b76ab2120 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -322,7 +322,9 @@ CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
SmallVector<CanQualType, 16> argTypes;
SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
- argTypes.push_back(DeriveThisType(MD->getParent(), MD));
+
+ const CXXRecordDecl *ThisType = TheCXXABI.getThisArgumentTypeForMethod(GD);
+ argTypes.push_back(DeriveThisType(ThisType, MD));
bool PassParams = true;
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index b889a4e05ee1..a9f3434589f2 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -33,10 +33,12 @@ struct MemberCallInfo {
}
static MemberCallInfo
-commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD,
+commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, GlobalDecl GD,
llvm::Value *This, llvm::Value *ImplicitParam,
QualType ImplicitParamTy, const CallExpr *CE,
CallArgList &Args, CallArgList *RtlArgs) {
+ auto *MD = cast<CXXMethodDecl>(GD.getDecl());
+
assert(CE == nullptr || isa<CXXMemberCallExpr>(CE) ||
isa<CXXOperatorCallExpr>(CE));
assert(MD->isInstance() &&
@@ -44,7 +46,7 @@ commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD,
// Push the this ptr.
const CXXRecordDecl *RD =
- CGF.CGM.getCXXABI().getThisArgumentTypeForMethod(MD);
+ CGF.CGM.getCXXABI().getThisArgumentTypeForMethod(GD);
Args.add(RValue::get(This), CGF.getTypes().DeriveThisType(RD, MD));
// If there is an implicit parameter (e.g. VTT), emit it.
@@ -110,7 +112,7 @@ RValue CodeGenFunction::EmitCXXDestructorCall(
}
CallArgList Args;
- commonEmitCXXMemberOrOperatorCall(*this, DtorDecl, This, ImplicitParam,
+ commonEmitCXXMemberOrOperatorCall(*this, Dtor, This, ImplicitParam,
ImplicitParamTy, CE, Args, nullptr);
return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee,
ReturnValueSlot(), Args, nullptr, CE && CE == MustTailCall,
@@ -285,7 +287,8 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
assert(ReturnValue.isNull() && "Constructor shouldn't have return value");
CallArgList Args;
commonEmitCXXMemberOrOperatorCall(
- *this, Ctor, This.getPointer(*this), /*ImplicitParam=*/nullptr,
+ *this, {Ctor, Ctor_Complete}, This.getPointer(*this),
+ /*ImplicitParam=*/nullptr,
/*ImplicitParamTy=*/QualType(), CE, Args, nullptr);
EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false,
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index ae785cce09f9..52d442cc587f 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -235,11 +235,24 @@ public:
void EmitCXXDestructors(const CXXDestructorDecl *D) override;
- const CXXRecordDecl *
- getThisArgumentTypeForMethod(const CXXMethodDecl *MD) override {
- if (MD->isVirtual() && !isa<CXXDestructorDecl>(MD)) {
+ const CXXRecordDecl *getThisArgumentTypeForMethod(GlobalDecl GD) override {
+ auto *MD = cast<CXXMethodDecl>(GD.getDecl());
+
+ if (MD->isVirtual()) {
+ GlobalDecl LookupGD = GD;
+ if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
+ // Complete dtors take a pointer to the complete object,
+ // thus don't need adjustment.
+ if (GD.getDtorType() == Dtor_Complete)
+ return MD->getParent();
+
+ // There's only Dtor_Deleting in vftable but it shares the this
+ // adjustment with the base one, so look up the deleting one instead.
+ LookupGD = GlobalDecl(DD, Dtor_Deleting);
+ }
MethodVFTableLocation ML =
- CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
+ CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
+
// The vbases might be ordered differently in the final overrider object
// and the complete object, so the "this" argument may sometimes point to
// memory that has no particular type (e.g. past the complete object).
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index a9119abad81d..9e2d7a85d100 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -2381,9 +2381,7 @@ class X86_64ABIInfo : public ABIInfo {
return false;
const llvm::Triple &Triple = getTarget().getTriple();
- if (Triple.isOSDarwin() || Triple.isPS())
- return false;
- if (Triple.isOSFreeBSD() && Triple.getOSMajorVersion() >= 10)
+ if (Triple.isOSDarwin() || Triple.isPS() || Triple.isOSFreeBSD())
return false;
return true;
}
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 661d9977fbc5..a268f2fa8fc5 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1873,14 +1873,12 @@ int Driver::ExecuteCompilation(
C.CleanupFileMap(C.getFailureResultFiles(), JA, true);
}
-#if LLVM_ON_UNIX
- // llvm/lib/Support/Unix/Signals.inc will exit with a special return code
+ // llvm/lib/Support/*/Signals.inc will exit with a special return code
// for SIGPIPE. Do not print diagnostics for this case.
if (CommandRes == EX_IOERR) {
Res = CommandRes;
continue;
}
-#endif
// Print extra information about abnormal failures, if possible.
//
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 52bee6a755ff..068a34a54a92 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -19,6 +19,7 @@
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/TargetParser/RISCVTargetParser.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
#include <memory>
@@ -545,7 +546,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
if ((Kinds & SanitizerKind::ShadowCallStack) &&
((TC.getTriple().isAArch64() &&
!llvm::AArch64::isX18ReservedByDefault(TC.getTriple())) ||
- TC.getTriple().isRISCV()) &&
+ (TC.getTriple().isRISCV() &&
+ !llvm::RISCV::isX18ReservedByDefault(TC.getTriple()))) &&
!Args.hasArg(options::OPT_ffixed_x18) && DiagnoseErrors) {
D.Diag(diag::err_drv_argument_only_allowed_with)
<< lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack)
diff --git a/clang/lib/Driver/ToolChains/Arch/PPC.cpp b/clang/lib/Driver/ToolChains/Arch/PPC.cpp
index 6ec736bc701b..e3c025fb2468 100644
--- a/clang/lib/Driver/ToolChains/Arch/PPC.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/PPC.cpp
@@ -34,53 +34,60 @@ static std::string getPPCGenericTargetCPU(const llvm::Triple &T) {
return "ppc";
}
-/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
-std::string ppc::getPPCTargetCPU(const ArgList &Args, const llvm::Triple &T) {
- if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
- StringRef CPUName = A->getValue();
-
- // Clang/LLVM does not actually support code generation
- // for the 405 CPU. However, there are uses of this CPU ID
- // in projects that previously used GCC and rely on Clang
- // accepting it. Clang has always ignored it and passed the
- // generic CPU ID to the back end.
- if (CPUName == "generic" || CPUName == "405")
+static std::string normalizeCPUName(StringRef CPUName, const llvm::Triple &T) {
+ // Clang/LLVM does not actually support code generation
+ // for the 405 CPU. However, there are uses of this CPU ID
+ // in projects that previously used GCC and rely on Clang
+ // accepting it. Clang has always ignored it and passed the
+ // generic CPU ID to the back end.
+ if (CPUName == "generic" || CPUName == "405")
+ return getPPCGenericTargetCPU(T);
+
+ if (CPUName == "native") {
+ std::string CPU = std::string(llvm::sys::getHostCPUName());
+ if (!CPU.empty() && CPU != "generic")
+ return CPU;
+ else
return getPPCGenericTargetCPU(T);
+ }
- if (CPUName == "native") {
- std::string CPU = std::string(llvm::sys::getHostCPUName());
- if (!CPU.empty() && CPU != "generic")
- return CPU;
- else
- return getPPCGenericTargetCPU(T);
- }
+ return llvm::StringSwitch<const char *>(CPUName)
+ .Case("common", "generic")
+ .Case("440fp", "440")
+ .Case("630", "pwr3")
+ .Case("G3", "g3")
+ .Case("G4", "g4")
+ .Case("G4+", "g4+")
+ .Case("8548", "e500")
+ .Case("G5", "g5")
+ .Case("power3", "pwr3")
+ .Case("power4", "pwr4")
+ .Case("power5", "pwr5")
+ .Case("power5x", "pwr5x")
+ .Case("power6", "pwr6")
+ .Case("power6x", "pwr6x")
+ .Case("power7", "pwr7")
+ .Case("power8", "pwr8")
+ .Case("power9", "pwr9")
+ .Case("power10", "pwr10")
+ .Case("future", "future")
+ .Case("powerpc", "ppc")
+ .Case("powerpc64", "ppc64")
+ .Case("powerpc64le", "ppc64le")
+ .Default(CPUName.data());
+}
- return llvm::StringSwitch<const char *>(CPUName)
- .Case("common", "generic")
- .Case("440fp", "440")
- .Case("630", "pwr3")
- .Case("G3", "g3")
- .Case("G4", "g4")
- .Case("G4+", "g4+")
- .Case("8548", "e500")
- .Case("G5", "g5")
- .Case("power3", "pwr3")
- .Case("power4", "pwr4")
- .Case("power5", "pwr5")
- .Case("power5x", "pwr5x")
- .Case("power6", "pwr6")
- .Case("power6x", "pwr6x")
- .Case("power7", "pwr7")
- .Case("power8", "pwr8")
- .Case("power9", "pwr9")
- .Case("power10", "pwr10")
- .Case("future", "future")
- .Case("powerpc", "ppc")
- .Case("powerpc64", "ppc64")
- .Case("powerpc64le", "ppc64le")
- .Default(CPUName.data());
- }
+/// Get the (LLVM) name of the PowerPC cpu we are tuning for.
+std::string ppc::getPPCTuneCPU(const ArgList &Args, const llvm::Triple &T) {
+ if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))
+ return normalizeCPUName(A->getValue(), T);
+ return getPPCGenericTargetCPU(T);
+}
+/// Get the (LLVM) name of the PowerPC cpu we are targeting.
+std::string ppc::getPPCTargetCPU(const ArgList &Args, const llvm::Triple &T) {
+ if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
+ return normalizeCPUName(A->getValue(), T);
return getPPCGenericTargetCPU(T);
}
diff --git a/clang/lib/Driver/ToolChains/Arch/PPC.h b/clang/lib/Driver/ToolChains/Arch/PPC.h
index cd2b47d392b6..97ac45083852 100644
--- a/clang/lib/Driver/ToolChains/Arch/PPC.h
+++ b/clang/lib/Driver/ToolChains/Arch/PPC.h
@@ -37,6 +37,8 @@ FloatABI getPPCFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
std::string getPPCTargetCPU(const llvm::opt::ArgList &Args,
const llvm::Triple &T);
+std::string getPPCTuneCPU(const llvm::opt::ArgList &Args,
+ const llvm::Triple &T);
const char *getPPCAsmModeForCPU(StringRef Name);
ReadGOTPtrMode getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3d40e19c83a5..ec6860113b7e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1989,22 +1989,19 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
void Clang::AddPPCTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
+ const llvm::Triple &T = getToolChain().getTriple();
if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
CmdArgs.push_back("-tune-cpu");
- if (strcmp(A->getValue(), "native") == 0)
- CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName()));
- else
- CmdArgs.push_back(A->getValue());
+ std::string CPU = ppc::getPPCTuneCPU(Args, T);
+ CmdArgs.push_back(Args.MakeArgString(CPU));
}
// Select the ABI to use.
const char *ABIName = nullptr;
- const llvm::Triple &T = getToolChain().getTriple();
if (T.isOSBinFormatELF()) {
switch (getToolChain().getArch()) {
case llvm::Triple::ppc64: {
- if ((T.isOSFreeBSD() && T.getOSMajorVersion() >= 13) ||
- T.isOSOpenBSD() || T.isMusl())
+ if (T.isPPC64ELFv2ABI())
ABIName = "elfv2";
else
ABIName = "elfv1";
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index 9a231c06a074..aa125bb308e8 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -446,13 +446,8 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
std::string OutputFileName = TC.getInputFilename(Output);
// If we are invoking `nvlink` internally we need to output a `.cubin` file.
- // Checking if the output is a temporary is the cleanest way to determine
- // this. Putting this logic in `getInputFilename` isn't an option because it
- // relies on the compilation.
// FIXME: This should hopefully be removed if NVIDIA updates their tooling.
- if (Output.isFilename() &&
- llvm::find(C.getTempFiles(), Output.getFilename()) !=
- C.getTempFiles().end()) {
+ if (!C.getInputArgs().getLastArg(options::OPT_c)) {
SmallString<256> Filename(Output.getFilename());
llvm::sys::path::replace_extension(Filename, "cubin");
OutputFileName = Filename.str();
diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp
index 64935227b07e..9a5af638c399 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -176,10 +176,8 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("/libexec/ld-elf.so.1");
}
const llvm::Triple &T = ToolChain.getTriple();
- if (T.getOSMajorVersion() >= 9) {
- if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc || T.isX86())
- CmdArgs.push_back("--hash-style=both");
- }
+ if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc || T.isX86())
+ CmdArgs.push_back("--hash-style=both");
CmdArgs.push_back("--enable-new-dtags");
}
@@ -396,17 +394,11 @@ FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple,
getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib"));
}
-ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const {
- unsigned Major = getTriple().getOSMajorVersion();
- if (Major >= 10 || Major == 0)
- return ToolChain::CST_Libcxx;
- return ToolChain::CST_Libstdcxx;
-}
-
unsigned FreeBSD::GetDefaultDwarfVersion() const {
- if (getTriple().getOSMajorVersion() < 12)
- return 2;
- return 4;
+ unsigned Major = getTriple().getOSMajorVersion();
+ if (Major >= 12 || Major == 0)
+ return 4;
+ return 2;
}
void FreeBSD::AddClangSystemIncludeArgs(
@@ -449,30 +441,14 @@ void FreeBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
concat(getDriver().SysRoot, "/usr/include/c++/v1"));
}
-void FreeBSD::addLibStdCxxIncludePaths(
- const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const {
- addLibStdCXXIncludePaths(concat(getDriver().SysRoot, "/usr/include/c++/4.2"),
- "", "", DriverArgs, CC1Args);
-}
-
void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
- CXXStdlibType Type = GetCXXStdlibType(Args);
unsigned Major = getTriple().getOSMajorVersion();
bool Profiling = Args.hasArg(options::OPT_pg) && Major != 0 && Major < 14;
- switch (Type) {
- case ToolChain::CST_Libcxx:
- CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
- if (Args.hasArg(options::OPT_fexperimental_library))
- CmdArgs.push_back("-lc++experimental");
- break;
-
- case ToolChain::CST_Libstdcxx:
- CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++");
- break;
- }
+ CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
+ if (Args.hasArg(options::OPT_fexperimental_library))
+ CmdArgs.push_back("-lc++experimental");
}
void FreeBSD::AddCudaIncludeArgs(const ArgList &DriverArgs,
@@ -550,8 +526,9 @@ SanitizerMask FreeBSD::getSupportedSanitizers() const {
void FreeBSD::addClangTargetOptions(const ArgList &DriverArgs,
ArgStringList &CC1Args,
Action::OffloadKind) const {
+ unsigned Major = getTriple().getOSMajorVersion();
if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
options::OPT_fno_use_init_array,
- getTriple().getOSMajorVersion() >= 12))
+ (Major >= 12 || Major == 0)))
CC1Args.push_back("-fno-use-init-array");
}
diff --git a/clang/lib/Driver/ToolChains/FreeBSD.h b/clang/lib/Driver/ToolChains/FreeBSD.h
index 18832dad9884..9b24ef1a1e1c 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.h
+++ b/clang/lib/Driver/ToolChains/FreeBSD.h
@@ -61,12 +61,16 @@ public:
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
- CXXStdlibType GetDefaultCXXStdlibType() const override;
+
+ RuntimeLibType GetDefaultRuntimeLibType() const override {
+ return ToolChain::RLT_CompilerRT;
+ }
+ CXXStdlibType GetDefaultCXXStdlibType() const override {
+ return ToolChain::CST_Libcxx;
+ }
+
void addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
- void
- addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const override;
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp
index 9bdc3a791779..ea6d7d697770 100644
--- a/clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -447,13 +447,13 @@ SanitizerMask Fuchsia::getDefaultSanitizers() const {
SanitizerMask Res;
switch (getTriple().getArch()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::riscv64:
Res |= SanitizerKind::ShadowCallStack;
break;
case llvm::Triple::x86_64:
Res |= SanitizerKind::SafeStack;
break;
default:
- // TODO: Enable SafeStack on RISC-V once tested.
break;
}
return Res;
diff --git a/clang/lib/Format/IntegerLiteralSeparatorFixer.cpp b/clang/lib/Format/IntegerLiteralSeparatorFixer.cpp
index ef07ab06760b..05e37c34a8a0 100644
--- a/clang/lib/Format/IntegerLiteralSeparatorFixer.cpp
+++ b/clang/lib/Format/IntegerLiteralSeparatorFixer.cpp
@@ -132,8 +132,11 @@ IntegerLiteralSeparatorFixer::process(const Environment &Env,
continue;
if (Start > 0)
Location = Location.getLocWithOffset(Start);
- cantFail(Result.add(tooling::Replacement(SourceMgr, Location, Length,
- format(Text, DigitsPerGroup))));
+ if (const auto &Formatted = format(Text, DigitsPerGroup);
+ Formatted != Text) {
+ cantFail(Result.add(
+ tooling::Replacement(SourceMgr, Location, Length, Formatted)));
+ }
}
return {Result, 0};
diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp
index cef8b36ff758..609b412380f8 100644
--- a/clang/lib/Format/QualifierAlignmentFixer.cpp
+++ b/clang/lib/Format/QualifierAlignmentFixer.cpp
@@ -280,8 +280,11 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
// The case `const Foo &&` -> `Foo const &&`
// The case `const std::Foo &&` -> `std::Foo const &&`
// The case `const std::Foo<T> &&` -> `std::Foo<T> const &&`
- while (Next && Next->isOneOf(tok::identifier, tok::coloncolon))
+ // However, `const Bar::*` remains the same.
+ while (Next && Next->isOneOf(tok::identifier, tok::coloncolon) &&
+ !Next->startsSequence(tok::coloncolon, tok::star)) {
Next = Next->Next;
+ }
if (Next && Next->is(TT_TemplateOpener)) {
Next = Next->MatchingParen;
// Move to the end of any template class members e.g.
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 3e58b6f90559..7e3957e62d3a 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -3849,13 +3849,13 @@ void UnwrappedLineParser::parseJavaEnumBody() {
void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
const FormatToken &InitialToken = *FormatTok;
nextToken();
+ handleAttributes();
// The actual identifier can be a nested name specifier, and in macros
// it is often token-pasted.
- // An [[attribute]] can be before the identifier.
while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
tok::kw___attribute, tok::kw___declspec,
- tok::kw_alignas, tok::l_square, tok::r_square) ||
+ tok::kw_alignas) ||
((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
FormatTok->isOneOf(tok::period, tok::comma))) {
if (Style.isJavaScript() &&
@@ -3873,15 +3873,10 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
FormatTok->is(tok::identifier) &&
FormatTok->TokenText != FormatTok->TokenText.upper();
nextToken();
- // We can have macros or attributes in between 'class' and the class name.
+ // We can have macros in between 'class' and the class name.
if (!IsNonMacroIdentifier) {
if (FormatTok->is(tok::l_paren)) {
parseParens();
- } else if (FormatTok->is(TT_AttributeSquare)) {
- parseSquare();
- // Consume the closing TT_AttributeSquare.
- if (FormatTok->Next && FormatTok->is(TT_AttributeSquare))
- nextToken();
}
}
}
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index ecc1c4cf51c1..ac9f8f8ed51c 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1983,14 +1983,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
Module = PP->getHeaderSearchInfo().lookupModule(
ModuleName, ImportLoc, /*AllowSearch*/ true,
/*AllowExtraModuleMapSearch*/ !IsInclusionDirective);
- /// FIXME: perhaps we should (a) look for a module using the module name
- // to file map (PrebuiltModuleFiles) and (b) diagnose if still not found?
- //if (Module == nullptr) {
- // getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
- // << ModuleName;
- // DisableGeneratingGlobalModuleIndex = true;
- // return ModuleLoadResult();
- //}
+
MM.cacheModuleLoad(*Path[0].first, Module);
} else {
ModuleLoadResult Result = findOrCompileModuleAndReadAST(
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index bbc271e5611e..76d0d53ed31d 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1637,35 +1637,14 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
Tok.setKind(tok::string_literal);
} else if (II == Ident__FLT_EVAL_METHOD__) {
// __FLT_EVAL_METHOD__ is set to the default value.
- if (getTUFPEvalMethod() ==
- LangOptions::FPEvalMethodKind::FEM_Indeterminable) {
- // This is possible if `AllowFPReassoc` or `AllowReciprocal` is enabled.
- // These modes can be triggered via the command line option `-ffast-math`
- // or via a `pragam float_control`.
- // __FLT_EVAL_METHOD__ expands to -1.
- // The `minus` operator is the next token we read from the stream.
- auto Toks = std::make_unique<Token[]>(1);
- OS << "-";
- Tok.setKind(tok::minus);
- // Push the token `1` to the stream.
- Token NumberToken;
- NumberToken.startToken();
- NumberToken.setKind(tok::numeric_constant);
- NumberToken.setLiteralData("1");
- NumberToken.setLength(1);
- Toks[0] = NumberToken;
- EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion*/ false,
- /*IsReinject*/ false);
- } else {
- OS << getTUFPEvalMethod();
- // __FLT_EVAL_METHOD__ expands to a simple numeric value.
- Tok.setKind(tok::numeric_constant);
- if (getLastFPEvalPragmaLocation().isValid()) {
- // The program is ill-formed. The value of __FLT_EVAL_METHOD__ is
- // altered by the pragma.
- Diag(Tok, diag::err_illegal_use_of_flt_eval_macro);
- Diag(getLastFPEvalPragmaLocation(), diag::note_pragma_entered_here);
- }
+ OS << getTUFPEvalMethod();
+ // __FLT_EVAL_METHOD__ expands to a simple numeric value.
+ Tok.setKind(tok::numeric_constant);
+ if (getLastFPEvalPragmaLocation().isValid()) {
+ // The program is ill-formed. The value of __FLT_EVAL_METHOD__ is altered
+ // by the pragma.
+ Diag(Tok, diag::err_illegal_use_of_flt_eval_macro);
+ Diag(getLastFPEvalPragmaLocation(), diag::note_pragma_entered_here);
}
} else if (II == Ident__COUNTER__) {
// __COUNTER__ expands to a simple numeric value.
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index fe9adb5685e3..0d411abf8f1c 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -207,11 +207,6 @@ void Preprocessor::Initialize(const TargetInfo &Target,
else
// Set initial value of __FLT_EVAL_METHOD__ from the command line.
setCurrentFPEvalMethod(SourceLocation(), getLangOpts().getFPEvalMethod());
- // When `-ffast-math` option is enabled, it triggers several driver math
- // options to be enabled. Among those, only one the following two modes
- // affect the eval-method: reciprocal or reassociate.
- if (getLangOpts().AllowFPReassoc || getLangOpts().AllowRecip)
- setCurrentFPEvalMethod(SourceLocation(), LangOptions::FEM_Indeterminable);
}
void Preprocessor::InitializeForModelFile() {
@@ -873,6 +868,7 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
CurLexerKind != CLK_CachingLexer) {
ModuleImportLoc = Identifier.getLocation();
NamedModuleImportPath.clear();
+ IsAtImport = true;
ModuleImportExpectsIdentifier = true;
CurLexerKind = CLK_LexAfterModuleImport;
}
@@ -940,6 +936,7 @@ void Preprocessor::Lex(Token &Result) {
case tok::semi:
TrackGMFState.handleSemi();
StdCXXImportSeqState.handleSemi();
+ ModuleDeclState.handleSemi();
break;
case tok::header_name:
case tok::annot_header_unit:
@@ -948,6 +945,13 @@ void Preprocessor::Lex(Token &Result) {
case tok::kw_export:
TrackGMFState.handleExport();
StdCXXImportSeqState.handleExport();
+ ModuleDeclState.handleExport();
+ break;
+ case tok::colon:
+ ModuleDeclState.handleColon();
+ break;
+ case tok::period:
+ ModuleDeclState.handlePeriod();
break;
case tok::identifier:
if (Result.getIdentifierInfo()->isModulesImport()) {
@@ -956,18 +960,25 @@ void Preprocessor::Lex(Token &Result) {
if (StdCXXImportSeqState.afterImportSeq()) {
ModuleImportLoc = Result.getLocation();
NamedModuleImportPath.clear();
+ IsAtImport = false;
ModuleImportExpectsIdentifier = true;
CurLexerKind = CLK_LexAfterModuleImport;
}
break;
} else if (Result.getIdentifierInfo() == getIdentifierInfo("module")) {
TrackGMFState.handleModule(StdCXXImportSeqState.afterTopLevelSeq());
+ ModuleDeclState.handleModule();
break;
+ } else {
+ ModuleDeclState.handleIdentifier(Result.getIdentifierInfo());
+ if (ModuleDeclState.isModuleCandidate())
+ break;
}
[[fallthrough]];
default:
TrackGMFState.handleMisc();
StdCXXImportSeqState.handleMisc();
+ ModuleDeclState.handleMisc();
break;
}
}
@@ -1151,6 +1162,15 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
if (NamedModuleImportPath.empty() && getLangOpts().CPlusPlusModules) {
if (LexHeaderName(Result))
return true;
+
+ if (Result.is(tok::colon) && ModuleDeclState.isNamedModule()) {
+ std::string Name = ModuleDeclState.getPrimaryName().str();
+ Name += ":";
+ NamedModuleImportPath.push_back(
+ {getIdentifierInfo(Name), Result.getLocation()});
+ CurLexerKind = CLK_LexAfterModuleImport;
+ return true;
+ }
} else {
Lex(Result);
}
@@ -1164,9 +1184,10 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
/*DisableMacroExpansion*/ true, /*IsReinject*/ false);
};
+ bool ImportingHeader = Result.is(tok::header_name);
// Check for a header-name.
SmallVector<Token, 32> Suffix;
- if (Result.is(tok::header_name)) {
+ if (ImportingHeader) {
// Enter the header-name token into the token stream; a Lex action cannot
// both return a token and cache tokens (doing so would corrupt the token
// cache if the call to Lex comes from CachingLex / PeekAhead).
@@ -1244,8 +1265,8 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
if (ModuleImportExpectsIdentifier && Result.getKind() == tok::identifier) {
// We expected to see an identifier here, and we did; continue handling
// identifiers.
- NamedModuleImportPath.push_back(std::make_pair(Result.getIdentifierInfo(),
- Result.getLocation()));
+ NamedModuleImportPath.push_back(
+ std::make_pair(Result.getIdentifierInfo(), Result.getLocation()));
ModuleImportExpectsIdentifier = false;
CurLexerKind = CLK_LexAfterModuleImport;
return true;
@@ -1285,7 +1306,8 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
std::string FlatModuleName;
if (getLangOpts().ModulesTS || getLangOpts().CPlusPlusModules) {
for (auto &Piece : NamedModuleImportPath) {
- if (!FlatModuleName.empty())
+ // If the FlatModuleName ends with colon, it implies it is a partition.
+ if (!FlatModuleName.empty() && FlatModuleName.back() != ':')
FlatModuleName += ".";
FlatModuleName += Piece.first->getName();
}
@@ -1296,7 +1318,8 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
}
Module *Imported = nullptr;
- if (getLangOpts().Modules) {
+ // We don't/shouldn't load the standard c++20 modules when preprocessing.
+ if (getLangOpts().Modules && !isInImportingCXXNamedModules()) {
Imported = TheModuleLoader.loadModule(ModuleImportLoc,
NamedModuleImportPath,
Module::Hidden,
@@ -1304,6 +1327,7 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
if (Imported)
makeModuleVisible(Imported, SemiLoc);
}
+
if (Callbacks)
Callbacks->moduleImport(ModuleImportLoc, NamedModuleImportPath, Imported);
diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp
index c6968b9f417e..ebe7dd66c118 100644
--- a/clang/lib/Lex/TokenLexer.cpp
+++ b/clang/lib/Lex/TokenLexer.cpp
@@ -1020,8 +1020,16 @@ static void updateConsecutiveMacroArgTokens(SourceManager &SM,
SourceLocation Limit =
SM.getComposedLoc(BeginFID, SM.getFileIDSize(BeginFID));
Partition = All.take_while([&](const Token &T) {
- return T.getLocation() >= BeginLoc && T.getLocation() < Limit &&
- NearLast(T.getLocation());
+ // NOTE: the Limit is included! The lexer recovery only ever inserts a
+ // single token past the end of the FileID, specifically the ) when a
+ // macro-arg containing a comma should be guarded by parentheses.
+ //
+ // It is safe to include the Limit here because SourceManager allocates
+ // FileSize + 1 for each SLocEntry.
+ //
+ // See https://github.com/llvm/llvm-project/issues/60722.
+ return T.getLocation() >= BeginLoc && T.getLocation() <= Limit
+ && NearLast(T.getLocation());
});
}
assert(!Partition.empty());
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 42f582724564..3ea97f6aa8f2 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -565,13 +565,6 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
case PFC_Precise:
NewFPFeatures.setFPPreciseEnabled(true);
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
- if (PP.getCurrentFPEvalMethod() ==
- LangOptions::FPEvalMethodKind::FEM_Indeterminable &&
- PP.getLastFPEvalPragmaLocation().isValid())
- // A preceding `pragma float_control(precise,off)` has changed
- // the value of the evaluation method.
- // Set it back to its old value.
- PP.setCurrentFPEvalMethod(SourceLocation(), PP.getLastFPEvalMethod());
break;
case PFC_NoPrecise:
if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict)
@@ -581,10 +574,6 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
else
NewFPFeatures.setFPPreciseEnabled(false);
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
- PP.setLastFPEvalMethod(PP.getCurrentFPEvalMethod());
- // `AllowFPReassoc` or `AllowReciprocal` option is enabled.
- PP.setCurrentFPEvalMethod(
- Loc, LangOptions::FPEvalMethodKind::FEM_Indeterminable);
break;
case PFC_Except:
if (!isPreciseFPEnabled())
@@ -608,12 +597,6 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
}
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
NewFPFeatures = FpPragmaStack.CurrentValue;
- if (CurFPFeatures.getAllowFPReassociate() ||
- CurFPFeatures.getAllowReciprocal())
- // Since we are popping the pragma, we don't want to be passing
- // a location here.
- PP.setCurrentFPEvalMethod(SourceLocation(),
- CurFPFeatures.getFPEvalMethod());
break;
}
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index f52c0247f01c..194239ab0e10 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -337,20 +337,29 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc,
}
case ModuleDeclKind::Implementation: {
- std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
- PP.getIdentifierInfo(ModuleName), Path[0].second);
// C++20 A module-declaration that contains neither an export-
// keyword nor a module-partition implicitly imports the primary
// module interface unit of the module as if by a module-import-
// declaration.
+ std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
+ PP.getIdentifierInfo(ModuleName), Path[0].second);
+
+ // The module loader will assume we're trying to import the module that
+ // we're building if `LangOpts.CurrentModule` equals to 'ModuleName'.
+ // Change the value for `LangOpts.CurrentModule` temporarily to make the
+ // module loader work properly.
+ const_cast<LangOptions&>(getLangOpts()).CurrentModule = "";
Mod = getModuleLoader().loadModule(ModuleLoc, {ModuleNameLoc},
Module::AllVisible,
/*IsInclusionDirective=*/false);
+ const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName;
+
if (!Mod) {
Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
// Create an empty module interface unit for error recovery.
Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
}
+
} break;
case ModuleDeclKind::PartitionImplementation:
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index b40bd0978a8a..890cea1dfb0e 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2540,8 +2540,6 @@ private:
TInfo->getType(), TInfo, LocEnd, Ctor);
Guide->setImplicit();
Guide->setParams(Params);
- if (Ctor && Ctor->getTrailingRequiresClause())
- Guide->setTrailingRequiresClause(Ctor->getTrailingRequiresClause());
for (auto *Param : Params)
Param->setDeclContext(Guide);
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 9e48a2a35a34..1fe2d3fac685 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -756,11 +756,8 @@ private:
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
- UnexpandedParameterPack U = Unexpanded[I];
- if (U.first.is<const SubstTemplateTypeParmPackType *>() ||
- U.first.is<const SubstNonTypeTemplateParmPackExpr *>())
- continue;
- auto [Depth, Index] = getDepthAndIndex(U);
+ unsigned Depth, Index;
+ std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
if (Depth == Info.getDeducedDepth())
AddPack(Index);
}
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 01a435668d88..86268b504cbb 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -89,23 +89,6 @@ namespace {
return true;
}
- bool
- VisitSubstTemplateTypeParmPackTypeLoc(SubstTemplateTypeParmPackTypeLoc TL) {
- Unexpanded.push_back({TL.getTypePtr(), TL.getNameLoc()});
- return true;
- }
-
- bool VisitSubstTemplateTypeParmPackType(SubstTemplateTypeParmPackType *T) {
- Unexpanded.push_back({T, SourceLocation()});
- return true;
- }
-
- bool
- VisitSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr *E) {
- Unexpanded.push_back({E, E->getParameterPackLocation()});
- return true;
- }
-
/// Record occurrences of function and non-type template
/// parameter packs in an expression.
bool VisitDeclRefExpr(DeclRefExpr *E) {
@@ -324,8 +307,7 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack);
return TTPD && TTPD->getTypeForDecl() == TTPT;
}
- return declaresSameEntity(Pack.first.get<const NamedDecl *>(),
- LocalPack);
+ return declaresSameEntity(Pack.first.get<NamedDecl *>(), LocalPack);
};
if (llvm::any_of(LSI->LocalPacks, DeclaresThisPack))
LambdaParamPackReferences.push_back(Pack);
@@ -377,7 +359,7 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
= Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
Name = TTP->getIdentifier();
else
- Name = Unexpanded[I].first.get<const NamedDecl *>()->getIdentifier();
+ Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
if (Name && NamesKnown.insert(Name).second)
Names.push_back(Name);
@@ -440,7 +422,7 @@ bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
for (auto Parm : Unexpanded)
- if (ParmSet.contains(Parm.first.dyn_cast<const NamedDecl *>()))
+ if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl *>()))
UnexpandedParms.push_back(Parm);
if (UnexpandedParms.empty())
return false;
@@ -692,95 +674,109 @@ bool Sema::CheckParameterPacksForExpansion(
bool &RetainExpansion, std::optional<unsigned> &NumExpansions) {
ShouldExpand = true;
RetainExpansion = false;
- std::pair<const IdentifierInfo *, SourceLocation> FirstPack;
- std::optional<std::pair<unsigned, SourceLocation>> PartialExpansion;
- std::optional<unsigned> CurNumExpansions;
+ std::pair<IdentifierInfo *, SourceLocation> FirstPack;
+ bool HaveFirstPack = false;
+ std::optional<unsigned> NumPartialExpansions;
+ SourceLocation PartiallySubstitutedPackLoc;
- for (auto [P, Loc] : Unexpanded) {
+ for (UnexpandedParameterPack ParmPack : Unexpanded) {
// Compute the depth and index for this parameter pack.
- std::optional<std::pair<unsigned, unsigned>> Pos;
+ unsigned Depth = 0, Index = 0;
+ IdentifierInfo *Name;
+ bool IsVarDeclPack = false;
+
+ if (const TemplateTypeParmType *TTP =
+ ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
+ Depth = TTP->getDepth();
+ Index = TTP->getIndex();
+ Name = TTP->getIdentifier();
+ } else {
+ NamedDecl *ND = ParmPack.first.get<NamedDecl *>();
+ if (isa<VarDecl>(ND))
+ IsVarDeclPack = true;
+ else
+ std::tie(Depth, Index) = getDepthAndIndex(ND);
+
+ Name = ND->getIdentifier();
+ }
+
+ // Determine the size of this argument pack.
unsigned NewPackSize;
- const auto *ND = P.dyn_cast<const NamedDecl *>();
- if (ND && isa<VarDecl>(ND)) {
- const auto *DAP =
- CurrentInstantiationScope->findInstantiationOf(ND)
- ->dyn_cast<LocalInstantiationScope::DeclArgumentPack *>();
- if (!DAP) {
+ if (IsVarDeclPack) {
+ // Figure out whether we're instantiating to an argument pack or not.
+ typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
+
+ llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
+ CurrentInstantiationScope->findInstantiationOf(
+ ParmPack.first.get<NamedDecl *>());
+ if (Instantiation->is<DeclArgumentPack *>()) {
+ // We could expand this function parameter pack.
+ NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
+ } else {
// We can't expand this function parameter pack, so we can't expand
// the pack expansion.
ShouldExpand = false;
continue;
}
- NewPackSize = DAP->size();
- } else if (ND) {
- Pos = getDepthAndIndex(ND);
- } else if (const auto *TTP = P.dyn_cast<const TemplateTypeParmType *>()) {
- Pos = {TTP->getDepth(), TTP->getIndex()};
- ND = TTP->getDecl();
- // FIXME: We either should have some fallback for canonical TTP, or
- // never have canonical TTP here.
- } else if (const auto *STP =
- P.dyn_cast<const SubstTemplateTypeParmPackType *>()) {
- NewPackSize = STP->getNumArgs();
- ND = STP->getReplacedParameter();
} else {
- const auto *SEP = P.get<const SubstNonTypeTemplateParmPackExpr *>();
- NewPackSize = SEP->getArgumentPack().pack_size();
- ND = SEP->getParameterPack();
- }
-
- if (Pos) {
// If we don't have a template argument at this depth/index, then we
// cannot expand the pack expansion. Make a note of this, but we still
// want to check any parameter packs we *do* have arguments for.
- if (Pos->first >= TemplateArgs.getNumLevels() ||
- !TemplateArgs.hasTemplateArgument(Pos->first, Pos->second)) {
+ if (Depth >= TemplateArgs.getNumLevels() ||
+ !TemplateArgs.hasTemplateArgument(Depth, Index)) {
ShouldExpand = false;
continue;
}
+
// Determine the size of the argument pack.
- NewPackSize = TemplateArgs(Pos->first, Pos->second).pack_size();
- // C++0x [temp.arg.explicit]p9:
- // Template argument deduction can extend the sequence of template
- // arguments corresponding to a template parameter pack, even when the
- // sequence contains explicitly specified template arguments.
- if (CurrentInstantiationScope)
- if (const NamedDecl *PartialPack =
- CurrentInstantiationScope->getPartiallySubstitutedPack();
- PartialPack && getDepthAndIndex(PartialPack) == *Pos) {
+ NewPackSize = TemplateArgs(Depth, Index).pack_size();
+ }
+
+ // C++0x [temp.arg.explicit]p9:
+ // Template argument deduction can extend the sequence of template
+ // arguments corresponding to a template parameter pack, even when the
+ // sequence contains explicitly specified template arguments.
+ if (!IsVarDeclPack && CurrentInstantiationScope) {
+ if (NamedDecl *PartialPack =
+ CurrentInstantiationScope->getPartiallySubstitutedPack()) {
+ unsigned PartialDepth, PartialIndex;
+ std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
+ if (PartialDepth == Depth && PartialIndex == Index) {
RetainExpansion = true;
// We don't actually know the new pack size yet.
- PartialExpansion = {NewPackSize, Loc};
+ NumPartialExpansions = NewPackSize;
+ PartiallySubstitutedPackLoc = ParmPack.second;
continue;
}
+ }
}
- // FIXME: Workaround for Canonical TTP.
- const IdentifierInfo *Name = ND ? ND->getIdentifier() : nullptr;
- if (!CurNumExpansions) {
+ if (!NumExpansions) {
// The is the first pack we've seen for which we have an argument.
// Record it.
- CurNumExpansions = NewPackSize;
- FirstPack = {Name, Loc};
- } else if (NewPackSize != *CurNumExpansions) {
+ NumExpansions = NewPackSize;
+ FirstPack.first = Name;
+ FirstPack.second = ParmPack.second;
+ HaveFirstPack = true;
+ continue;
+ }
+
+ if (NewPackSize != *NumExpansions) {
// C++0x [temp.variadic]p5:
// All of the parameter packs expanded by a pack expansion shall have
// the same number of arguments specified.
- Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
- << FirstPack.first << Name << *CurNumExpansions << NewPackSize
- << SourceRange(FirstPack.second) << SourceRange(Loc);
+ if (HaveFirstPack)
+ Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
+ << FirstPack.first << Name << *NumExpansions << NewPackSize
+ << SourceRange(FirstPack.second) << SourceRange(ParmPack.second);
+ else
+ Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
+ << Name << *NumExpansions << NewPackSize
+ << SourceRange(ParmPack.second);
return true;
}
}
- if (NumExpansions && CurNumExpansions &&
- *NumExpansions != *CurNumExpansions) {
- Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
- << FirstPack.first << *CurNumExpansions << *NumExpansions
- << SourceRange(FirstPack.second);
- return true;
- }
-
// If we're performing a partial expansion but we also have a full expansion,
// expand to the number of common arguments. For example, given:
//
@@ -790,18 +786,17 @@ bool Sema::CheckParameterPacksForExpansion(
//
// ... a call to 'A<int, int>().f<int>' should expand the pack once and
// retain an expansion.
- if (PartialExpansion) {
- if (CurNumExpansions && *CurNumExpansions < PartialExpansion->first) {
+ if (NumPartialExpansions) {
+ if (NumExpansions && *NumExpansions < *NumPartialExpansions) {
NamedDecl *PartialPack =
CurrentInstantiationScope->getPartiallySubstitutedPack();
Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial)
- << PartialPack << PartialExpansion->first << *CurNumExpansions
- << SourceRange(PartialExpansion->second);
+ << PartialPack << *NumPartialExpansions << *NumExpansions
+ << SourceRange(PartiallySubstitutedPackLoc);
return true;
}
- NumExpansions = PartialExpansion->first;
- } else {
- NumExpansions = CurNumExpansions;
+
+ NumExpansions = NumPartialExpansions;
}
return false;
@@ -814,48 +809,47 @@ std::optional<unsigned> Sema::getNumArgumentsInExpansion(
CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
std::optional<unsigned> Result;
- auto setResultSz = [&Result](unsigned Size) {
- assert((!Result || *Result == Size) && "inconsistent pack sizes");
- Result = Size;
- };
- auto setResultPos = [&](const std::pair<unsigned, unsigned> &Pos) -> bool {
- unsigned Depth = Pos.first, Index = Pos.second;
- if (Depth >= TemplateArgs.getNumLevels() ||
- !TemplateArgs.hasTemplateArgument(Depth, Index))
- // The pattern refers to an unknown template argument. We're not ready to
- // expand this pack yet.
- return true;
- // Determine the size of the argument pack.
- setResultSz(TemplateArgs(Depth, Index).pack_size());
- return false;
- };
+ for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
+ // Compute the depth and index for this parameter pack.
+ unsigned Depth;
+ unsigned Index;
- for (auto [I, _] : Unexpanded) {
- if (const auto *TTP = I.dyn_cast<const TemplateTypeParmType *>()) {
- if (setResultPos({TTP->getDepth(), TTP->getIndex()}))
- return std::nullopt;
- } else if (const auto *STP =
- I.dyn_cast<const SubstTemplateTypeParmPackType *>()) {
- setResultSz(STP->getNumArgs());
- } else if (const auto *SEP =
- I.dyn_cast<const SubstNonTypeTemplateParmPackExpr *>()) {
- setResultSz(SEP->getArgumentPack().pack_size());
+ if (const TemplateTypeParmType *TTP =
+ Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
+ Depth = TTP->getDepth();
+ Index = TTP->getIndex();
} else {
- const auto *ND = I.get<const NamedDecl *>();
- // Function parameter pack or init-capture pack.
+ NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
if (isa<VarDecl>(ND)) {
- const auto *DAP =
- CurrentInstantiationScope->findInstantiationOf(ND)
- ->dyn_cast<LocalInstantiationScope::DeclArgumentPack *>();
- if (!DAP)
+ // Function parameter pack or init-capture pack.
+ typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
+
+ llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
+ CurrentInstantiationScope->findInstantiationOf(
+ Unexpanded[I].first.get<NamedDecl *>());
+ if (Instantiation->is<Decl *>())
// The pattern refers to an unexpanded pack. We're not ready to expand
// this pack yet.
return std::nullopt;
- setResultSz(DAP->size());
- } else if (setResultPos(getDepthAndIndex(ND))) {
- return std::nullopt;
+
+ unsigned Size = Instantiation->get<DeclArgumentPack *>()->size();
+ assert((!Result || *Result == Size) && "inconsistent pack sizes");
+ Result = Size;
+ continue;
}
+
+ std::tie(Depth, Index) = getDepthAndIndex(ND);
}
+ if (Depth >= TemplateArgs.getNumLevels() ||
+ !TemplateArgs.hasTemplateArgument(Depth, Index))
+ // The pattern refers to an unknown template argument. We're not ready to
+ // expand this pack yet.
+ return std::nullopt;
+
+ // Determine the size of the argument pack.
+ unsigned Size = TemplateArgs(Depth, Index).pack_size();
+ assert((!Result || *Result == Size) && "inconsistent pack sizes");
+ Result = Size;
}
return Result;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 6a05ecc5370f..48bb28b56cd3 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4569,7 +4569,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
getSema(),
Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
: Sema::ExpressionEvaluationContext::ConstantEvaluated,
- /*LambdaContextDecl=*/nullptr, /*ExprContext=*/
+ Sema::ReuseLambdaContextDecl, /*ExprContext=*/
Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
Expr *InputExpr = Input.getSourceExpression();
@@ -5897,7 +5897,6 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(
= dyn_cast<PackExpansionType>(OldType)) {
// We have a function parameter pack that may need to be expanded.
QualType Pattern = Expansion->getPattern();
- NumExpansions = Expansion->getNumExpansions();
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
diff --git a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
index b35ab1fe23ce..b85d0adb8eaf 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
@@ -41,6 +41,10 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
if (!RetE)
return;
+ // Skip "body farmed" functions.
+ if (RetE->getSourceRange().isInvalid())
+ return;
+
SVal V = C.getSVal(RetE);
const MemRegion *R = V.getAsRegion();
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
index a7f149b87e79..c3bd4876faf2 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -766,7 +766,7 @@ PathDiagnosticPieceRef PathDiagnosticBuilder::generateDiagForSwitchOP(
case Stmt::CaseStmtClass: {
os << "Control jumps to 'case ";
const auto *Case = cast<CaseStmt>(S);
- const Expr *LHS = Case->getLHS()->IgnoreParenCasts();
+ const Expr *LHS = Case->getLHS()->IgnoreParenImpCasts();
// Determine if it is an enum.
bool GetRawInt = true;
diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 1017dff2b0f3..a275d36286d3 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -2678,7 +2678,18 @@ EquivalenceClass::simplify(SValBuilder &SVB, RangeSet::Factory &F,
if (OldState == State)
continue;
- assert(find(State, MemberSym) == find(State, SimplifiedMemberSym));
+ // Be aware that `SimplifiedMemberSym` might refer to an already dead
+ // symbol. In that case, the eqclass of that might not be the same as the
+ // eqclass of `MemberSym`. This is because the dead symbols are not
+ // preserved in the `ClassMap`, hence
+ // `find(State, SimplifiedMemberSym)` will result in a trivial eqclass
+ // compared to the eqclass of `MemberSym`.
+ // These eqclasses should be the same if `SimplifiedMemberSym` is alive.
+ // --> assert(find(State, MemberSym) == find(State, SimplifiedMemberSym))
+ //
+ // Note that `MemberSym` must be alive here since that is from the
+ // `ClassMembers` where all the symbols are alive.
+
// Remove the old and more complex symbol.
State = find(State, MemberSym).removeMember(State, MemberSym);
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
index 3fcef00a5780..ae1662237e87 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
@@ -40,67 +40,69 @@ DependencyScanningTool::DependencyScanningTool(
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
: Worker(Service, std::move(FS)) {}
-llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
- const std::vector<std::string> &CommandLine, StringRef CWD,
- std::optional<StringRef> ModuleName) {
- /// Prints out all of the gathered dependencies into a string.
- class MakeDependencyPrinterConsumer : public DependencyConsumer {
- public:
- void handleBuildCommand(Command) override {}
+namespace {
+/// Prints out all of the gathered dependencies into a string.
+class MakeDependencyPrinterConsumer : public DependencyConsumer {
+public:
+ void handleBuildCommand(Command) override {}
+
+ void
+ handleDependencyOutputOpts(const DependencyOutputOptions &Opts) override {
+ this->Opts = std::make_unique<DependencyOutputOptions>(Opts);
+ }
- void
- handleDependencyOutputOpts(const DependencyOutputOptions &Opts) override {
- this->Opts = std::make_unique<DependencyOutputOptions>(Opts);
- }
+ void handleFileDependency(StringRef File) override {
+ Dependencies.push_back(std::string(File));
+ }
- void handleFileDependency(StringRef File) override {
- Dependencies.push_back(std::string(File));
- }
+ void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override {
+ // Same as `handleModuleDependency`.
+ }
- void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override {
- // Same as `handleModuleDependency`.
- }
+ void handleModuleDependency(ModuleDeps MD) override {
+ // These are ignored for the make format as it can't support the full
+ // set of deps, and handleFileDependency handles enough for implicitly
+ // built modules to work.
+ }
- void handleModuleDependency(ModuleDeps MD) override {
- // These are ignored for the make format as it can't support the full
- // set of deps, and handleFileDependency handles enough for implicitly
- // built modules to work.
- }
+ void handleContextHash(std::string Hash) override {}
- void handleContextHash(std::string Hash) override {}
+ std::string lookupModuleOutput(const ModuleID &ID,
+ ModuleOutputKind Kind) override {
+ llvm::report_fatal_error("unexpected call to lookupModuleOutput");
+ }
- std::string lookupModuleOutput(const ModuleID &ID,
- ModuleOutputKind Kind) override {
- llvm::report_fatal_error("unexpected call to lookupModuleOutput");
- }
+ void printDependencies(std::string &S) {
+ assert(Opts && "Handled dependency output options.");
- void printDependencies(std::string &S) {
- assert(Opts && "Handled dependency output options.");
-
- class DependencyPrinter : public DependencyFileGenerator {
- public:
- DependencyPrinter(DependencyOutputOptions &Opts,
- ArrayRef<std::string> Dependencies)
- : DependencyFileGenerator(Opts) {
- for (const auto &Dep : Dependencies)
- addDependency(Dep);
- }
-
- void printDependencies(std::string &S) {
- llvm::raw_string_ostream OS(S);
- outputDependencyFile(OS);
- }
- };
-
- DependencyPrinter Generator(*Opts, Dependencies);
- Generator.printDependencies(S);
- }
+ class DependencyPrinter : public DependencyFileGenerator {
+ public:
+ DependencyPrinter(DependencyOutputOptions &Opts,
+ ArrayRef<std::string> Dependencies)
+ : DependencyFileGenerator(Opts) {
+ for (const auto &Dep : Dependencies)
+ addDependency(Dep);
+ }
- private:
- std::unique_ptr<DependencyOutputOptions> Opts;
- std::vector<std::string> Dependencies;
- };
+ void printDependencies(std::string &S) {
+ llvm::raw_string_ostream OS(S);
+ outputDependencyFile(OS);
+ }
+ };
+
+ DependencyPrinter Generator(*Opts, Dependencies);
+ Generator.printDependencies(S);
+ }
+
+protected:
+ std::unique_ptr<DependencyOutputOptions> Opts;
+ std::vector<std::string> Dependencies;
+};
+} // anonymous namespace
+llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
+ const std::vector<std::string> &CommandLine, StringRef CWD,
+ std::optional<StringRef> ModuleName) {
MakeDependencyPrinterConsumer Consumer;
auto Result =
Worker.computeDependencies(CWD, CommandLine, Consumer, ModuleName);
@@ -111,6 +113,50 @@ llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
return Output;
}
+llvm::Expected<P1689Rule> DependencyScanningTool::getP1689ModuleDependencyFile(
+ const CompileCommand &Command, StringRef CWD,
+ std::string &MakeformatOutput, std::string &MakeformatOutputPath) {
+ class P1689ModuleDependencyPrinterConsumer
+ : public MakeDependencyPrinterConsumer {
+ public:
+ P1689ModuleDependencyPrinterConsumer(P1689Rule &Rule,
+ const CompileCommand &Command)
+ : Filename(Command.Filename), Rule(Rule) {
+ Rule.PrimaryOutput = Command.Output;
+ }
+
+ void handleProvidedAndRequiredStdCXXModules(
+ std::optional<P1689ModuleInfo> Provided,
+ std::vector<P1689ModuleInfo> Requires) override {
+ Rule.Provides = Provided;
+ if (Rule.Provides)
+ Rule.Provides->SourcePath = Filename.str();
+ Rule.Requires = Requires;
+ }
+
+ StringRef getMakeFormatDependencyOutputPath() {
+ if (Opts->OutputFormat != DependencyOutputFormat::Make)
+ return {};
+ return Opts->OutputFile;
+ }
+
+ private:
+ StringRef Filename;
+ P1689Rule &Rule;
+ };
+
+ P1689Rule Rule;
+ P1689ModuleDependencyPrinterConsumer Consumer(Rule, Command);
+ auto Result = Worker.computeDependencies(CWD, Command.CommandLine, Consumer);
+ if (Result)
+ return std::move(Result);
+
+ MakeformatOutputPath = Consumer.getMakeFormatDependencyOutputPath();
+ if (!MakeformatOutputPath.empty())
+ Consumer.printDependencies(MakeformatOutput);
+ return Rule;
+}
+
llvm::Expected<FullDependenciesResult>
DependencyScanningTool::getFullDependencies(
const std::vector<std::string> &CommandLine, StringRef CWD,
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index b54b8de9157e..8eb0328d6322 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -247,10 +247,12 @@ public:
std::make_shared<DependencyConsumerForwarder>(
std::move(Opts), WorkingDirectory, Consumer));
break;
+ case ScanningOutputFormat::P1689:
case ScanningOutputFormat::Full:
MDC = std::make_shared<ModuleDepCollector>(
std::move(Opts), ScanInstance, Consumer, OriginalInvocation,
- OptimizeArgs, EagerLoadModules);
+ OptimizeArgs, EagerLoadModules,
+ Format == ScanningOutputFormat::P1689);
ScanInstance.addDependencyCollector(MDC);
break;
}
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index cb1c66b8d63f..d1cbf79a843e 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -339,6 +339,14 @@ void ModuleDepCollectorPP::InclusionDirective(
void ModuleDepCollectorPP::moduleImport(SourceLocation ImportLoc,
ModuleIdPath Path,
const Module *Imported) {
+ if (MDC.ScanInstance.getPreprocessor().isInImportingCXXNamedModules()) {
+ P1689ModuleInfo RequiredModule;
+ RequiredModule.ModuleName = Path[0].first->getName().str();
+ RequiredModule.Type = P1689ModuleInfo::ModuleType::NamedCXXModule;
+ MDC.RequiredStdCXXModules.push_back(RequiredModule);
+ return;
+ }
+
handleImport(Imported);
}
@@ -361,6 +369,21 @@ void ModuleDepCollectorPP::EndOfMainFile() {
.getFileEntryForID(MainFileID)
->getName());
+ auto &PP = MDC.ScanInstance.getPreprocessor();
+ if (PP.isInNamedModule()) {
+ P1689ModuleInfo ProvidedModule;
+ ProvidedModule.ModuleName = PP.getNamedModuleName();
+ ProvidedModule.Type = P1689ModuleInfo::ModuleType::NamedCXXModule;
+ ProvidedModule.IsStdCXXModuleInterface = PP.isInNamedInterfaceUnit();
+ // Don't put implementation (non partition) unit as Provide.
+ // Put the module as required instead. Since the implementation
+ // unit will import the primary module implicitly.
+ if (PP.isInImplementationUnit())
+ MDC.RequiredStdCXXModules.push_back(ProvidedModule);
+ else
+ MDC.ProvidedStdCXXModule = ProvidedModule;
+ }
+
if (!MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude.empty())
MDC.addFileDep(MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude);
@@ -374,6 +397,10 @@ void ModuleDepCollectorPP::EndOfMainFile() {
MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts);
+ if (MDC.IsStdModuleP1689Format)
+ MDC.Consumer.handleProvidedAndRequiredStdCXXModules(
+ MDC.ProvidedStdCXXModule, MDC.RequiredStdCXXModules);
+
for (auto &&I : MDC.ModularDeps)
MDC.Consumer.handleModuleDependency(*I.second);
@@ -548,10 +575,12 @@ void ModuleDepCollectorPP::addAffectingClangModule(
ModuleDepCollector::ModuleDepCollector(
std::unique_ptr<DependencyOutputOptions> Opts,
CompilerInstance &ScanInstance, DependencyConsumer &C,
- CompilerInvocation OriginalCI, bool OptimizeArgs, bool EagerLoadModules)
+ CompilerInvocation OriginalCI, bool OptimizeArgs, bool EagerLoadModules,
+ bool IsStdModuleP1689Format)
: ScanInstance(ScanInstance), Consumer(C), Opts(std::move(Opts)),
OriginalInvocation(std::move(OriginalCI)), OptimizeArgs(OptimizeArgs),
- EagerLoadModules(EagerLoadModules) {}
+ EagerLoadModules(EagerLoadModules),
+ IsStdModuleP1689Format(IsStdModuleP1689Format) {}
void ModuleDepCollector::attachToPreprocessor(Preprocessor &PP) {
PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(*this));
diff --git a/compiler-rt/lib/builtins/cpu_model.c b/compiler-rt/lib/builtins/cpu_model.c
index c5d7ae31afce..f5ad530c7e88 100644
--- a/compiler-rt/lib/builtins/cpu_model.c
+++ b/compiler-rt/lib/builtins/cpu_model.c
@@ -924,6 +924,9 @@ int CONSTRUCTOR_ATTRIBUTE __cpu_indicator_init(void) {
#define HWCAP_SB (1 << 29)
#endif
+#ifndef AT_HWCAP2
+#define AT_HWCAP2 26
+#endif
#ifndef HWCAP2_DCPODP
#define HWCAP2_DCPODP (1 << 0)
#endif
diff --git a/libcxx/include/__algorithm/ranges_binary_search.h b/libcxx/include/__algorithm/ranges_binary_search.h
index b2a8977652fb..d72d4e057401 100644
--- a/libcxx/include/__algorithm/ranges_binary_search.h
+++ b/libcxx/include/__algorithm/ranges_binary_search.h
@@ -36,7 +36,7 @@ struct __fn {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
- return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
+ return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
}
template <forward_range _Range, class _Type, class _Proj = identity,
@@ -46,7 +46,7 @@ struct __fn {
auto __first = ranges::begin(__r);
auto __last = ranges::end(__r);
auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
- return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
+ return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
}
};
} // namespace __binary_search
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 51b100fa5569..ac6a1422bfe3 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -904,7 +904,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
// Try to find out if RTTI is disabled.
# if !defined(__cpp_rtti) || __cpp_rtti < 199711L
-# define _LIBCPP_NO_RTTI
+# define _LIBCPP_HAS_NO_RTTI
# endif
# ifndef _LIBCPP_WEAK
@@ -1259,6 +1259,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
#endif
+// TODO(varconst): currently, there are bugs in Clang's intrinsics when handling Objective-C++ `id`, so don't use
+// compiler intrinsics in the Objective-C++ mode.
+# ifdef __OBJC__
+# define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS
+# endif
+
#endif // __cplusplus
#endif // _LIBCPP___CONFIG
diff --git a/libcxx/include/__format/concepts.h b/libcxx/include/__format/concepts.h
index fe4a7b9625ce..ba8d8e316226 100644
--- a/libcxx/include/__format/concepts.h
+++ b/libcxx/include/__format/concepts.h
@@ -66,9 +66,8 @@ concept formattable = __formattable<_Tp, _CharT>;
// TODO FMT Add a test to validate we fail when using that concept after P2165
// has been implemented.
template <class _Tp>
-concept __fmt_pair_like = __is_specialization_v<_Tp, pair> ||
- // Use a requires since tuple_size_v may fail to instantiate,
- (__is_specialization_v<_Tp, tuple> && requires { tuple_size_v<_Tp> == 2; });
+concept __fmt_pair_like =
+ __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2);
# endif //_LIBCPP_STD_VER > 20
#endif //_LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__format/formatter_floating_point.h b/libcxx/include/__format/formatter_floating_point.h
index a544b53f7e6d..ca065723e198 100644
--- a/libcxx/include/__format/formatter_floating_point.h
+++ b/libcxx/include/__format/formatter_floating_point.h
@@ -404,7 +404,6 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_
// In fixed mode the algorithm truncates trailing spaces and possibly the
// radix point. There's no good guess for the position of the radix point
// therefore scan the output after the first digit.
-
__result.__radix_point = _VSTD::find(__first, __result.__last, '.');
}
}
@@ -665,7 +664,7 @@ __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specif
if (__result.__exponent == __result.__last)
// if P > X >= -4, the conversion is with style f or F and precision P - 1 - X.
// By including the radix point it calculates P - (1 + X)
- __p -= __result.__radix_point - __buffer.begin();
+ __p -= __result.__radix_point - __result.__integral;
else
// otherwise, the conversion is with style e or E and precision P - 1.
--__p;
diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h
index ca79d334a028..9f92f6181468 100644
--- a/libcxx/include/__functional/function.h
+++ b/libcxx/include/__functional/function.h
@@ -268,10 +268,10 @@ public:
virtual void destroy() _NOEXCEPT = 0;
virtual void destroy_deallocate() _NOEXCEPT = 0;
virtual _Rp operator()(_ArgTypes&& ...) = 0;
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
virtual const void* target(const type_info&) const _NOEXCEPT = 0;
virtual const std::type_info& target_type() const _NOEXCEPT = 0;
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
// __func implements __base for a given functor type.
@@ -305,10 +305,10 @@ public:
virtual void destroy() _NOEXCEPT;
virtual void destroy_deallocate() _NOEXCEPT;
virtual _Rp operator()(_ArgTypes&&... __arg);
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
virtual const void* target(const type_info&) const _NOEXCEPT;
virtual const std::type_info& target_type() const _NOEXCEPT;
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
@@ -356,7 +356,7 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
const void*
@@ -374,7 +374,7 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
return typeid(_Fp);
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
// __value_func creates a value-type from a __func.
@@ -553,7 +553,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
_LIBCPP_INLINE_VISIBILITY
explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
_LIBCPP_INLINE_VISIBILITY
const std::type_info& target_type() const _NOEXCEPT
{
@@ -569,7 +569,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
return nullptr;
return (const _Tp*)__f_->target(typeid(_Tp));
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
// Storage for a functor object, to be used with __policy to manage copy and
@@ -616,7 +616,7 @@ struct __policy
{
static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
true,
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
&typeid(void)
#else
nullptr
@@ -642,7 +642,7 @@ struct __policy
__choose_policy(/* is_small = */ false_type) {
static const _LIBCPP_CONSTEXPR __policy __policy_ = {
&__large_clone<_Fun>, &__large_destroy<_Fun>, false,
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
&typeid(typename _Fun::_Target)
#else
nullptr
@@ -657,7 +657,7 @@ struct __policy
{
static const _LIBCPP_CONSTEXPR __policy __policy_ = {
nullptr, nullptr, false,
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
&typeid(typename _Fun::_Target)
#else
nullptr
@@ -861,7 +861,7 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
return !__policy_->__is_null;
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
_LIBCPP_INLINE_VISIBILITY
const std::type_info& target_type() const _NOEXCEPT
{
@@ -878,7 +878,7 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
else
return reinterpret_cast<const _Tp*>(&__buf_.__small);
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME)
@@ -945,7 +945,7 @@ public:
return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
virtual const void* target(type_info const& __ti) const _NOEXCEPT {
if (__ti == typeid(__func::__block_type))
return &__f_;
@@ -955,7 +955,7 @@ public:
virtual const std::type_info& target_type() const _NOEXCEPT {
return typeid(__func::__block_type);
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
#endif // _LIBCPP_HAS_EXTENSION_BLOCKS
@@ -1056,12 +1056,12 @@ public:
// function invocation:
_Rp operator()(_ArgTypes...) const;
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
// function target access:
const std::type_info& target_type() const _NOEXCEPT;
template <typename _Tp> _Tp* target() _NOEXCEPT;
template <typename _Tp> const _Tp* target() const _NOEXCEPT;
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
};
#if _LIBCPP_STD_VER >= 17
@@ -1156,7 +1156,7 @@ function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template<class _Rp, class ..._ArgTypes>
const std::type_info&
@@ -1181,7 +1181,7 @@ function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
return __f_.template target<_Tp>();
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
template <class _Rp, class... _ArgTypes>
inline _LIBCPP_INLINE_VISIBILITY
diff --git a/libcxx/include/__memory/construct_at.h b/libcxx/include/__memory/construct_at.h
index ffee0022c243..14484dd6aa0d 100644
--- a/libcxx/include/__memory/construct_at.h
+++ b/libcxx/include/__memory/construct_at.h
@@ -83,6 +83,16 @@ _ForwardIterator __destroy(_ForwardIterator __first, _ForwardIterator __last) {
return __first;
}
+template <class _BidirectionalIterator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+_BidirectionalIterator __reverse_destroy(_BidirectionalIterator __first, _BidirectionalIterator __last) {
+ while (__last != __first) {
+ --__last;
+ std::__destroy_at(std::addressof(*__last));
+ }
+ return __last;
+}
+
#if _LIBCPP_STD_VER > 14
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index b77ce9230bff..f0ffa26abfeb 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -219,7 +219,7 @@ public:
__shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
: __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
const void* __get_deleter(const type_info&) const _NOEXCEPT override;
#endif
@@ -228,7 +228,7 @@ private:
void __on_zero_shared_weak() _NOEXCEPT override;
};
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template <class _Tp, class _Dp, class _Alloc>
const void*
@@ -237,7 +237,7 @@ __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) cons
return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
template <class _Tp, class _Dp, class _Alloc>
void
@@ -260,7 +260,10 @@ __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
__a.deallocate(_PTraits::pointer_to(*this), 1);
}
-struct __default_initialize_tag {};
+// This tag is used to instantiate an allocator type. The various shared_ptr control blocks
+// detect that the allocator has been instantiated for this type and perform alternative
+// initialization/destruction based on that.
+struct __for_overwrite_tag {};
template <class _Tp, class _Alloc>
struct __shared_ptr_emplace
@@ -271,25 +274,20 @@ struct __shared_ptr_emplace
explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
: __storage_(_VSTD::move(__a))
{
-#if _LIBCPP_STD_VER > 17
- using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
- _TpAlloc __tmp(*__get_alloc());
- allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
+#if _LIBCPP_STD_VER >= 20
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ static_assert(sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
+ ::new ((void*)__get_elem()) _Tp;
+ } else {
+ using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
+ _TpAlloc __tmp(*__get_alloc());
+ allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
+ }
#else
::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...);
#endif
}
-
-#if _LIBCPP_STD_VER >= 20
- _LIBCPP_HIDE_FROM_ABI
- explicit __shared_ptr_emplace(__default_initialize_tag, _Alloc __a)
- : __storage_(std::move(__a))
- {
- ::new ((void*)__get_elem()) _Tp;
- }
-#endif
-
_LIBCPP_HIDE_FROM_ABI
_Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
@@ -299,9 +297,13 @@ struct __shared_ptr_emplace
private:
void __on_zero_shared() _NOEXCEPT override {
#if _LIBCPP_STD_VER > 17
- using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
- _TpAlloc __tmp(*__get_alloc());
- allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ __get_elem()->~_Tp();
+ } else {
+ using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
+ _TpAlloc __tmp(*__get_alloc());
+ allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
+ }
#else
__get_elem()->~_Tp();
#endif
@@ -367,13 +369,57 @@ public:
template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
-template<class _Tp, class _Up>
+// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6
+// A pointer type Y* is said to be compatible with a pointer type T*
+// when either Y* is convertible to T* or Y is U[N] and T is cv U[].
+#if _LIBCPP_STD_VER >= 17
+template <class _Yp, class _Tp>
+struct __bounded_convertible_to_unbounded : false_type {};
+
+template <class _Up, std::size_t _Np, class _Tp>
+struct __bounded_convertible_to_unbounded<_Up[_Np], _Tp>
+ : is_same<__remove_cv_t<_Tp>, _Up[]> {};
+
+template <class _Yp, class _Tp>
struct __compatible_with
-#if _LIBCPP_STD_VER > 14
- : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {};
+ : _Or<
+ is_convertible<_Yp*, _Tp*>,
+ __bounded_convertible_to_unbounded<_Yp, _Tp>
+ > {};
#else
- : is_convertible<_Tp*, _Up*> {};
-#endif // _LIBCPP_STD_VER > 14
+template <class _Yp, class _Tp>
+struct __compatible_with
+ : is_convertible<_Yp*, _Tp*> {};
+#endif // _LIBCPP_STD_VER >= 17
+
+// Constructors that take raw pointers have a different set of "compatible" constraints
+// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1
+// - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*,
+// or T is U[] and Y(*)[] is convertible to T*.
+// - If T is not an array type, then Y* is convertible to T*.
+#if _LIBCPP_STD_VER >= 17
+template <class _Yp, class _Tp, class = void>
+struct __raw_pointer_compatible_with : _And<
+ _Not<is_array<_Tp>>,
+ is_convertible<_Yp*, _Tp*>
+ > {};
+
+template <class _Yp, class _Up, std::size_t _Np>
+struct __raw_pointer_compatible_with<_Yp, _Up[_Np], __enable_if_t<
+ is_convertible<_Yp(*)[_Np], _Up(*)[_Np]>::value> >
+ : true_type {};
+
+template <class _Yp, class _Up>
+struct __raw_pointer_compatible_with<_Yp, _Up[], __enable_if_t<
+ is_convertible<_Yp(*)[], _Up(*)[]>::value> >
+ : true_type {};
+
+#else
+template <class _Yp, class _Tp>
+struct __raw_pointer_compatible_with
+ : is_convertible<_Yp*, _Tp*> {};
+#endif // _LIBCPP_STD_VER >= 17
+
template <class _Ptr, class = void>
struct __is_deletable : false_type { };
@@ -395,12 +441,12 @@ static false_type __well_formed_deleter_test(...);
template <class _Dp, class _Pt>
struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {};
-template<class _Dp, class _Tp, class _Yp>
+template<class _Dp, class _Yp, class _Tp>
struct __shared_ptr_deleter_ctor_reqs
{
- static const bool value = __compatible_with<_Tp, _Yp>::value &&
+ static const bool value = __raw_pointer_compatible_with<_Yp, _Tp>::value &&
is_move_constructible<_Dp>::value &&
- __well_formed_deleter<_Dp, _Tp*>::value;
+ __well_formed_deleter<_Dp, _Yp*>::value;
};
#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
@@ -439,7 +485,7 @@ public:
template<class _Yp, class = __enable_if_t<
_And<
- __compatible_with<_Yp, _Tp>
+ __raw_pointer_compatible_with<_Yp, _Tp>
// In C++03 we get errors when trying to do SFINAE with the
// delete operator, so we always pretend that it's deletable.
// The same happens on GCC.
@@ -457,7 +503,7 @@ public:
__enable_weak_this(__p, __p);
}
- template<class _Yp, class _Dp, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value> >
+ template<class _Yp, class _Dp, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
_LIBCPP_HIDE_FROM_ABI
shared_ptr(_Yp* __p, _Dp __d)
: __ptr_(__p)
@@ -484,7 +530,7 @@ public:
#endif // _LIBCPP_NO_EXCEPTIONS
}
- template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value> >
+ template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
_LIBCPP_HIDE_FROM_ABI
shared_ptr(_Yp* __p, _Dp __d, _Alloc __a)
: __ptr_(__p)
@@ -646,6 +692,7 @@ public:
template <class _Yp, class _Dp, class = __enable_if_t<
!is_lvalue_reference<_Dp>::value &&
+ __compatible_with<_Yp, _Tp>::value &&
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
> >
_LIBCPP_HIDE_FROM_ABI
@@ -668,6 +715,7 @@ public:
template <class _Yp, class _Dp, class = void, class = __enable_if_t<
is_lvalue_reference<_Dp>::value &&
+ __compatible_with<_Yp, _Tp>::value &&
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
> >
_LIBCPP_HIDE_FROM_ABI
@@ -740,9 +788,10 @@ public:
}
#endif
- template <class _Yp, class _Dp, class = __enable_if_t<
- is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
- > >
+ template <class _Yp, class _Dp, class = __enable_if_t<_And<
+ __compatible_with<_Yp, _Tp>,
+ is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>
+ >::value> >
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r)
{
@@ -764,7 +813,7 @@ public:
}
template<class _Yp, class = __enable_if_t<
- __compatible_with<_Yp, _Tp>::value
+ __raw_pointer_compatible_with<_Yp, _Tp>::value
> >
_LIBCPP_HIDE_FROM_ABI
void reset(_Yp* __p)
@@ -773,8 +822,7 @@ public:
}
template<class _Yp, class _Dp, class = __enable_if_t<
- __compatible_with<_Yp, _Tp>::value
- > >
+ __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
_LIBCPP_HIDE_FROM_ABI
void reset(_Yp* __p, _Dp __d)
{
@@ -782,8 +830,7 @@ public:
}
template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<
- __compatible_with<_Yp, _Tp>::value
- > >
+ __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
_LIBCPP_HIDE_FROM_ABI
void reset(_Yp* __p, _Dp __d, _Alloc __a)
{
@@ -858,7 +905,7 @@ public:
}
#endif
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template <class _Dp>
_LIBCPP_HIDE_FROM_ABI
_Dp* __get_deleter() const _NOEXCEPT
@@ -867,7 +914,7 @@ public:
? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
: nullptr);
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
template<class _Yp, class _CntrlBlk>
_LIBCPP_HIDE_FROM_ABI
@@ -963,12 +1010,9 @@ template<class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
{
- using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
- using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
- __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
- ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__default_initialize_tag{}, __a);
- auto __control_block = __guard.__release_ptr();
- return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block));
+ using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
+ _ForOverwriteAllocator __alloc(__a);
+ return std::allocate_shared<_Tp>(__alloc);
}
template<class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
@@ -1000,26 +1044,25 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count, _Tp const& __arg)
: __alloc_(__alloc), __count_(__count)
{
- std::__uninitialized_allocator_fill_n(__alloc_, std::begin(__data_), __count_, __arg);
+ std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::begin(__data_), __count_, __arg);
}
_LIBCPP_HIDE_FROM_ABI
explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count)
: __alloc_(__alloc), __count_(__count)
{
- std::__uninitialized_allocator_value_construct_n(__alloc_, std::begin(__data_), __count_);
- }
-
#if _LIBCPP_STD_VER >= 20
- _LIBCPP_HIDE_FROM_ABI
- explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count, __default_initialize_tag)
- : __alloc_(__alloc), __count_(__count)
- {
- // We are purposefully not using an allocator-aware default construction because the spec says so.
- // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
- std::uninitialized_default_construct_n(std::begin(__data_), __count_);
- }
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ // We are purposefully not using an allocator-aware default construction because the spec says so.
+ // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
+ std::uninitialized_default_construct_n(std::begin(__data_), __count_);
+ } else {
+ std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
+ }
+#else
+ std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
#endif
+ }
// Returns the number of bytes required to store a control block followed by the given number
// of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
@@ -1042,8 +1085,17 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
private:
void __on_zero_shared() _NOEXCEPT override {
+#if _LIBCPP_STD_VER >= 20
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ std::__reverse_destroy(__data_, __data_ + __count_);
+ } else {
+ __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
+ std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
+ }
+#else
__allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
+#endif
}
void __on_zero_shared_weak() _NOEXCEPT override {
@@ -1096,30 +1148,40 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc>
_LIBCPP_HIDE_FROM_ABI
explicit __bounded_array_control_block(_Alloc const& __alloc, _Tp const& __arg) : __alloc_(__alloc) {
- std::__uninitialized_allocator_fill_n(__alloc_, std::addressof(__data_[0]), _Count, __arg);
+ std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count, __arg);
}
_LIBCPP_HIDE_FROM_ABI
explicit __bounded_array_control_block(_Alloc const& __alloc) : __alloc_(__alloc) {
- std::__uninitialized_allocator_value_construct_n(__alloc_, std::addressof(__data_[0]), _Count);
- }
-
#if _LIBCPP_STD_VER >= 20
- _LIBCPP_HIDE_FROM_ABI
- explicit __bounded_array_control_block(_Alloc const& __alloc, __default_initialize_tag) : __alloc_(__alloc) {
- // We are purposefully not using an allocator-aware default construction because the spec says so.
- // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
- std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count);
- }
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ // We are purposefully not using an allocator-aware default construction because the spec says so.
+ // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
+ std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count);
+ } else {
+ std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
+ }
+#else
+ std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
#endif
+ }
_LIBCPP_HIDE_FROM_ABI_VIRTUAL
~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
private:
void __on_zero_shared() _NOEXCEPT override {
+#if _LIBCPP_STD_VER >= 20
+ if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
+ std::__reverse_destroy(__data_, __data_ + _Count);
+ } else {
+ __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
+ std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
+ }
+#else
__allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
+#endif
}
void __on_zero_shared_weak() _NOEXCEPT override {
@@ -1175,7 +1237,9 @@ template<class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, in
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
{
- return std::__allocate_shared_bounded_array<_Tp>(__a, __default_initialize_tag{});
+ using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
+ _ForOverwriteAllocator __alloc(__a);
+ return std::__allocate_shared_bounded_array<_Tp>(__alloc);
}
template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
@@ -1196,7 +1260,7 @@ template<class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> make_shared_for_overwrite()
{
- return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __default_initialize_tag{});
+ return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>());
}
// unbounded array variants
@@ -1218,7 +1282,9 @@ template<class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value,
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n)
{
- return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __default_initialize_tag{});
+ using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
+ _ForOverwriteAllocator __alloc(__a);
+ return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n);
}
template<class _Tp, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
@@ -1239,7 +1305,7 @@ template<class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> make_shared_for_overwrite(size_t __n)
{
- return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __default_initialize_tag{});
+ return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
}
#endif // _LIBCPP_STD_VER > 17
@@ -1465,7 +1531,7 @@ reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
-#ifndef _LIBCPP_NO_RTTI
+#ifndef _LIBCPP_HAS_NO_RTTI
template<class _Dp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1475,7 +1541,7 @@ get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
return __p.template __get_deleter<_Dp>();
}
-#endif // _LIBCPP_NO_RTTI
+#endif // _LIBCPP_HAS_NO_RTTI
template<class _Tp>
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h
index 63a45b2ac87b..0067780c3f5d 100644
--- a/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/libcxx/include/__memory/uninitialized_algorithms.h
@@ -410,7 +410,7 @@ constexpr void __allocator_destroy_multidimensional(_Alloc& __alloc, _BidirIter
// This function assumes that the allocator is bound to the correct type.
template<class _Alloc, class _Tp>
_LIBCPP_HIDE_FROM_ABI
-constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) {
+constexpr void __allocator_construct_at_multidimensional(_Alloc& __alloc, _Tp* __loc) {
static_assert(is_same_v<typename allocator_traits<_Alloc>::value_type, _Tp>,
"The allocator should already be rebound to the correct type");
@@ -426,7 +426,7 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) {
});
for (; __i != extent_v<_Tp>; ++__i) {
- std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]));
+ std::__allocator_construct_at_multidimensional(__elem_alloc, std::addressof(__array[__i]));
}
__guard.__complete();
} else {
@@ -446,13 +446,13 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc) {
// This function assumes that the allocator is bound to the correct type.
template<class _Alloc, class _Tp, class _Arg>
_LIBCPP_HIDE_FROM_ABI
-constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const& __arg) {
+constexpr void __allocator_construct_at_multidimensional(_Alloc& __alloc, _Tp* __loc, _Arg const& __arg) {
static_assert(is_same_v<typename allocator_traits<_Alloc>::value_type, _Tp>,
"The allocator should already be rebound to the correct type");
if constexpr (is_array_v<_Tp>) {
static_assert(is_array_v<_Arg>,
- "Provided non-array initialization argument to __allocator_construct_at when "
+ "Provided non-array initialization argument to __allocator_construct_at_multidimensional when "
"trying to construct an array.");
using _Element = remove_extent_t<_Tp>;
@@ -465,7 +465,7 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const&
std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i);
});
for (; __i != extent_v<_Tp>; ++__i) {
- std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]), __arg[__i]);
+ std::__allocator_construct_at_multidimensional(__elem_alloc, std::addressof(__array[__i]), __arg[__i]);
}
__guard.__complete();
} else {
@@ -481,8 +481,8 @@ constexpr void __allocator_construct_at(_Alloc& __alloc, _Tp* __loc, _Arg const&
// initialization using allocator_traits destruction. If the elements in the range are C-style
// arrays, they are initialized element-wise using allocator construction, and recursively so.
template<class _Alloc, class _BidirIter, class _Tp, class _Size = typename iterator_traits<_BidirIter>::difference_type>
-_LIBCPP_HIDE_FROM_ABI
-constexpr void __uninitialized_allocator_fill_n(_Alloc& __alloc, _BidirIter __it, _Size __n, _Tp const& __value) {
+_LIBCPP_HIDE_FROM_ABI constexpr void
+__uninitialized_allocator_fill_n_multidimensional(_Alloc& __alloc, _BidirIter __it, _Size __n, _Tp const& __value) {
using _ValueType = typename iterator_traits<_BidirIter>::value_type;
__allocator_traits_rebind_t<_Alloc, _ValueType> __value_alloc(__alloc);
_BidirIter __begin = __it;
@@ -490,16 +490,16 @@ constexpr void __uninitialized_allocator_fill_n(_Alloc& __alloc, _BidirIter __it
// If an exception is thrown, destroy what we have constructed so far in reverse order.
__exception_guard __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
for (; __n != 0; --__n, ++__it) {
- std::__allocator_construct_at(__value_alloc, std::addressof(*__it), __value);
+ std::__allocator_construct_at_multidimensional(__value_alloc, std::addressof(*__it), __value);
}
__guard.__complete();
}
-// Same as __uninitialized_allocator_fill_n, but doesn't pass any initialization argument
+// Same as __uninitialized_allocator_fill_n_multidimensional, but doesn't pass any initialization argument
// to the allocator's construct method, which results in value initialization.
-template<class _Alloc, class _BidirIter, class _Size = typename iterator_traits<_BidirIter>::difference_type>
-_LIBCPP_HIDE_FROM_ABI
-constexpr void __uninitialized_allocator_value_construct_n(_Alloc& __alloc, _BidirIter __it, _Size __n) {
+template <class _Alloc, class _BidirIter, class _Size = typename iterator_traits<_BidirIter>::difference_type>
+_LIBCPP_HIDE_FROM_ABI constexpr void
+__uninitialized_allocator_value_construct_n_multidimensional(_Alloc& __alloc, _BidirIter __it, _Size __n) {
using _ValueType = typename iterator_traits<_BidirIter>::value_type;
__allocator_traits_rebind_t<_Alloc, _ValueType> __value_alloc(__alloc);
_BidirIter __begin = __it;
@@ -507,7 +507,7 @@ constexpr void __uninitialized_allocator_value_construct_n(_Alloc& __alloc, _Bid
// If an exception is thrown, destroy what we have constructed so far in reverse order.
__exception_guard __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
for (; __n != 0; --__n, ++__it) {
- std::__allocator_construct_at(__value_alloc, std::addressof(*__it));
+ std::__allocator_construct_at_multidimensional(__value_alloc, std::addressof(*__it));
}
__guard.__complete();
}
diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h
index 3afd6ddbe8f2..997380ee9c65 100644
--- a/libcxx/include/__ranges/elements_view.h
+++ b/libcxx/include/__ranges/elements_view.h
@@ -49,12 +49,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
-template <class _View, size_t _Np, bool _Const>
-class __elements_view_iterator;
-
-template <class _View, size_t _Np, bool _Const>
-class __elements_view_sentinel;
-
template <class _Tp, size_t _Np>
concept __has_tuple_element = __tuple_like<_Tp> && _Np < tuple_size<_Tp>::value;
@@ -66,6 +60,13 @@ template <input_range _View, size_t _Np>
__has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
__returnable_element<range_reference_t<_View>, _Np>
class elements_view : public view_interface<elements_view<_View, _Np>> {
+private:
+ template <bool>
+ class __iterator;
+
+ template <bool>
+ class __sentinel;
+
public:
_LIBCPP_HIDE_FROM_ABI elements_view()
requires default_initializable<_View>
@@ -130,12 +131,6 @@ public:
}
private:
- template <bool _Const>
- using __iterator = __elements_view_iterator<_View, _Np, _Const>;
-
- template <bool _Const>
- using __sentinel = __elements_view_sentinel<_View, _Np, _Const>;
-
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
};
@@ -160,13 +155,18 @@ struct __elements_view_iterator_category_base<_Base, _Np> {
using iterator_category = decltype(__get_iterator_category());
};
-template <class _View, size_t _Np, bool _Const>
-class __elements_view_iterator : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> {
- template <class, size_t, bool >
- friend class __elements_view_iterator;
+template <input_range _View, size_t _Np>
+ requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&
+ __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
+ __returnable_element<range_reference_t<_View>, _Np>
+template <bool _Const>
+class elements_view<_View, _Np>::__iterator
+ : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> {
+ template <bool>
+ friend class __iterator;
- template <class, size_t, bool >
- friend class __elements_view_sentinel;
+ template <bool>
+ friend class __sentinel;
using _Base = __maybe_const<_Const, _View>;
@@ -198,14 +198,13 @@ public:
using value_type = remove_cvref_t<tuple_element_t<_Np, range_value_t<_Base>>>;
using difference_type = range_difference_t<_Base>;
- _LIBCPP_HIDE_FROM_ABI __elements_view_iterator()
+ _LIBCPP_HIDE_FROM_ABI __iterator()
requires default_initializable<iterator_t<_Base>>
= default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __elements_view_iterator(iterator_t<_Base> __current)
- : __current_(std::move(__current)) {}
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {}
- _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator(__elements_view_iterator<_View, _Np, !_Const> __i)
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
: __current_(std::move(__i.__current_)) {}
@@ -215,14 +214,14 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return __get_element(__current_); }
- _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator++() {
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
++__current_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; }
- _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator operator++(int)
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
requires forward_range<_Base>
{
auto temp = *this;
@@ -230,14 +229,14 @@ public:
return temp;
}
- _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator--()
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
requires bidirectional_range<_Base>
{
--__current_;
return *this;
}
- _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator operator--(int)
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
requires bidirectional_range<_Base>
{
auto temp = *this;
@@ -245,14 +244,14 @@ public:
return temp;
}
- _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator+=(difference_type __n)
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
requires random_access_range<_Base>
{
__current_ += __n;
return *this;
}
- _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator-=(difference_type __n)
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)
requires random_access_range<_Base>
{
__current_ -= __n;
@@ -265,99 +264,91 @@ public:
return __get_element(__current_ + __n);
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator==(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
requires equality_comparable<iterator_t<_Base>>
{
return __x.__current_ == __y.__current_;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator<(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ < __y.__current_;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator>(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __y < __x;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator<=(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return !(__y < __x);
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator>=(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return !(__x < __y);
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr auto
- operator<=>(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
{
return __x.__current_ <=> __y.__current_;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator
- operator+(const __elements_view_iterator& __x, difference_type __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __x, difference_type __y)
requires random_access_range<_Base>
{
- return __elements_view_iterator{__x} += __y;
+ return __iterator{__x} += __y;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator
- operator+(difference_type __x, const __elements_view_iterator& __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __y + __x;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator
- operator-(const __elements_view_iterator& __x, difference_type __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __x, difference_type __y)
requires random_access_range<_Base>
{
- return __elements_view_iterator{__x} -= __y;
+ return __iterator{__x} -= __y;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type
- operator-(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
{
return __x.__current_ - __y.__current_;
}
};
-template <class _View, size_t _Np, bool _Const>
-class __elements_view_sentinel {
+template <input_range _View, size_t _Np>
+ requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&
+ __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
+ __returnable_element<range_reference_t<_View>, _Np>
+template <bool _Const>
+class elements_view<_View, _Np>::__sentinel {
private:
using _Base = __maybe_const<_Const, _View>;
_LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>();
- template <class, size_t, bool >
- friend class __elements_view_sentinel;
+ template <bool>
+ friend class __sentinel;
template <bool _AnyConst>
- _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
- __get_current(const __elements_view_iterator<_View, _Np, _AnyConst>& __iter) {
+ _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_current(const __iterator<_AnyConst>& __iter) {
return (__iter.__current_);
}
public:
- _LIBCPP_HIDE_FROM_ABI __elements_view_sentinel() = default;
+ _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __elements_view_sentinel(sentinel_t<_Base> __end)
- : __end_(std::move(__end)) {}
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
- _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_sentinel(__elements_view_sentinel<_View, _Np, !_Const> __other)
+ _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __other)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__other.__end_)) {}
@@ -365,22 +356,21 @@ public:
template <bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator==(const __elements_view_iterator<_View, _Np, _OtherConst>& __x, const __elements_view_sentinel& __y) {
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __get_current(__x) == __y.__end_;
}
template <bool _OtherConst>
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
- operator-(const __elements_view_iterator<_View, _Np, _OtherConst>& __x, const __elements_view_sentinel& __y) {
+ operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __get_current(__x) - __y.__end_;
}
template <bool _OtherConst>
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
- operator-(const __elements_view_sentinel& __x, const __elements_view_iterator<_View, _Np, _OtherConst>& __y) {
+ operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
return __x.__end_ - __get_current(__y);
}
};
diff --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h
index f8633a3fee84..e14a9abeb9e7 100644
--- a/libcxx/include/__ranges/filter_view.h
+++ b/libcxx/include/__ranges/filter_view.h
@@ -46,15 +46,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
namespace ranges {
-
- template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
- requires view<_View> && is_object_v<_Pred>
- class __filter_view_iterator;
-
- template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
- requires view<_View> && is_object_v<_Pred>
- class __filter_view_sentinel;
-
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
requires view<_View> && is_object_v<_Pred>
class filter_view : public view_interface<filter_view<_View, _Pred>> {
@@ -67,11 +58,8 @@ namespace ranges {
using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
- using __iterator = __filter_view_iterator<_View, _Pred>;
- using __sentinel = __filter_view_sentinel<_View, _Pred>;
-
- friend __iterator;
- friend __sentinel;
+ class __iterator;
+ class __sentinel;
public:
_LIBCPP_HIDE_FROM_ABI
@@ -131,13 +119,11 @@ namespace ranges {
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
requires view<_View> && is_object_v<_Pred>
- class __filter_view_iterator : public __filter_iterator_category<_View> {
-
- using __filter_view = filter_view<_View, _Pred>;
+ class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> {
public:
_LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>();
- _LIBCPP_NO_UNIQUE_ADDRESS __filter_view* __parent_ = nullptr;
+ _LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr;
using iterator_concept =
_If<bidirectional_range<_View>, bidirectional_iterator_tag,
@@ -149,10 +135,10 @@ namespace ranges {
using difference_type = range_difference_t<_View>;
_LIBCPP_HIDE_FROM_ABI
- __filter_view_iterator() requires default_initializable<iterator_t<_View>> = default;
+ __iterator() requires default_initializable<iterator_t<_View>> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr __filter_view_iterator(__filter_view& __parent, iterator_t<_View> __current)
+ constexpr __iterator(filter_view& __parent, iterator_t<_View> __current)
: __current_(std::move(__current)), __parent_(std::addressof(__parent))
{ }
@@ -171,7 +157,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __filter_view_iterator& operator++() {
+ constexpr __iterator& operator++() {
__current_ = ranges::find_if(std::move(++__current_), ranges::end(__parent_->__base_),
std::ref(*__parent_->__pred_));
return *this;
@@ -179,42 +165,42 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr void operator++(int) { ++*this; }
_LIBCPP_HIDE_FROM_ABI
- constexpr __filter_view_iterator operator++(int) requires forward_range<_View> {
+ constexpr __iterator operator++(int) requires forward_range<_View> {
auto __tmp = *this;
++*this;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __filter_view_iterator& operator--() requires bidirectional_range<_View> {
+ constexpr __iterator& operator--() requires bidirectional_range<_View> {
do {
--__current_;
} while (!std::invoke(*__parent_->__pred_, *__current_));
return *this;
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __filter_view_iterator operator--(int) requires bidirectional_range<_View> {
+ constexpr __iterator operator--(int) requires bidirectional_range<_View> {
auto tmp = *this;
--*this;
return tmp;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(__filter_view_iterator const& __x, __filter_view_iterator const& __y)
+ friend constexpr bool operator==(__iterator const& __x, __iterator const& __y)
requires equality_comparable<iterator_t<_View>>
{
return __x.__current_ == __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr range_rvalue_reference_t<_View> iter_move(__filter_view_iterator const& __it)
+ friend constexpr range_rvalue_reference_t<_View> iter_move(__iterator const& __it)
noexcept(noexcept(ranges::iter_move(__it.__current_)))
{
return ranges::iter_move(__it.__current_);
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr void iter_swap(__filter_view_iterator const& __x, __filter_view_iterator const& __y)
+ friend constexpr void iter_swap(__iterator const& __x, __iterator const& __y)
noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
requires indirectly_swappable<iterator_t<_View>>
{
@@ -224,17 +210,15 @@ namespace ranges {
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
requires view<_View> && is_object_v<_Pred>
- class __filter_view_sentinel {
- using __filter_view = filter_view<_View, _Pred>;
-
+ class filter_view<_View, _Pred>::__sentinel {
public:
sentinel_t<_View> __end_ = sentinel_t<_View>();
_LIBCPP_HIDE_FROM_ABI
- __filter_view_sentinel() = default;
+ __sentinel() = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit __filter_view_sentinel(__filter_view& __parent)
+ constexpr explicit __sentinel(filter_view& __parent)
: __end_(ranges::end(__parent.__base_))
{ }
@@ -242,7 +226,7 @@ namespace ranges {
constexpr sentinel_t<_View> base() const { return __end_; }
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator==(__filter_view_iterator<_View, _Pred> const& __x, __filter_view_sentinel const& __y) {
+ operator==(__iterator const& __x, __sentinel const& __y) {
return __x.__current_ == __y.__end_;
}
};
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index 3654096b7e17..8f9148a6849c 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -83,14 +83,6 @@ namespace ranges {
{ __j - __j } -> convertible_to<_IotaDiffT<_Iter>>;
};
- template <weakly_incrementable _Start>
- requires copyable<_Start>
- struct __iota_view_iterator;
-
- template <weakly_incrementable _Start, semiregular _BoundSentinel>
- requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
- struct __iota_view_sentinel;
-
template<class>
struct __iota_iterator_category {};
@@ -102,9 +94,211 @@ namespace ranges {
template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_sentinel_t>
requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
+ struct __iterator : public __iota_iterator_category<_Start> {
+ friend class iota_view;
+
+ using iterator_concept =
+ _If<__advanceable<_Start>, random_access_iterator_tag,
+ _If<__decrementable<_Start>, bidirectional_iterator_tag,
+ _If<incrementable<_Start>, forward_iterator_tag,
+ /*Else*/ input_iterator_tag>>>;
+
+ using value_type = _Start;
+ using difference_type = _IotaDiffT<_Start>;
+
+ _Start __value_ = _Start();
+
+ _LIBCPP_HIDE_FROM_ABI
+ __iterator() requires default_initializable<_Start> = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
+ return __value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator++() {
+ ++__value_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr void operator++(int) { ++*this; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator operator++(int) requires incrementable<_Start> {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator--() requires __decrementable<_Start> {
+ --__value_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator operator--(int) requires __decrementable<_Start> {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator+=(difference_type __n)
+ requires __advanceable<_Start>
+ {
+ if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
+ if (__n >= difference_type(0)) {
+ __value_ += static_cast<_Start>(__n);
+ } else {
+ __value_ -= static_cast<_Start>(-__n);
+ }
+ } else {
+ __value_ += __n;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iterator& operator-=(difference_type __n)
+ requires __advanceable<_Start>
+ {
+ if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
+ if (__n >= difference_type(0)) {
+ __value_ -= static_cast<_Start>(__n);
+ } else {
+ __value_ += static_cast<_Start>(-__n);
+ }
+ } else {
+ __value_ -= __n;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _Start operator[](difference_type __n) const
+ requires __advanceable<_Start>
+ {
+ return _Start(__value_ + __n);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
+ requires equality_comparable<_Start>
+ {
+ return __x.__value_ == __y.__value_;
+ }
- using __iterator = __iota_view_iterator<_Start>;
- using __sentinel = __iota_view_sentinel<_Start, _BoundSentinel>;
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return __x.__value_ < __y.__value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return __y < __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return !(__y < __x);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return !(__x < __y);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
+ requires totally_ordered<_Start> && three_way_comparable<_Start>
+ {
+ return __x.__value_ <=> __y.__value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iterator operator+(__iterator __i, difference_type __n)
+ requires __advanceable<_Start>
+ {
+ __i += __n;
+ return __i;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iterator operator+(difference_type __n, __iterator __i)
+ requires __advanceable<_Start>
+ {
+ return __i + __n;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iterator operator-(__iterator __i, difference_type __n)
+ requires __advanceable<_Start>
+ {
+ __i -= __n;
+ return __i;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
+ requires __advanceable<_Start>
+ {
+ if constexpr (__integer_like<_Start>) {
+ if constexpr (__signed_integer_like<_Start>) {
+ return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
+ }
+ if (__y.__value_ > __x.__value_) {
+ return difference_type(-difference_type(__y.__value_ - __x.__value_));
+ }
+ return difference_type(__x.__value_ - __y.__value_);
+ }
+ return __x.__value_ - __y.__value_;
+ }
+ };
+
+ struct __sentinel {
+ friend class iota_view;
+
+ private:
+ _BoundSentinel __bound_sentinel_ = _BoundSentinel();
+
+ public:
+ _LIBCPP_HIDE_FROM_ABI
+ __sentinel() = default;
+ constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
+ return __x.__value_ == __y.__bound_sentinel_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __sentinel& __y)
+ requires sized_sentinel_for<_BoundSentinel, _Start>
+ {
+ return __x.__value_ - __y.__bound_sentinel_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr iter_difference_t<_Start> operator-(const __sentinel& __x, const __iterator& __y)
+ requires sized_sentinel_for<_BoundSentinel, _Start>
+ {
+ return -(__y - __x);
+ }
+ };
_Start __value_ = _Start();
_BoundSentinel __bound_sentinel_ = _BoundSentinel();
@@ -185,224 +379,6 @@ namespace ranges {
template <class _Start, class _BoundSentinel>
inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
- template <weakly_incrementable _Start>
- requires copyable<_Start>
- struct __iota_view_iterator : public __iota_iterator_category<_Start> {
-
- template <weakly_incrementable _StartT, semiregular _BoundSentinelT>
- requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT>
- friend class iota_view;
-
- using iterator_concept =
- _If<__advanceable<_Start>, random_access_iterator_tag,
- _If<__decrementable<_Start>, bidirectional_iterator_tag,
- _If<incrementable<_Start>, forward_iterator_tag,
- /*Else*/ input_iterator_tag>>>;
-
- using value_type = _Start;
- using difference_type = _IotaDiffT<_Start>;
-
- _Start __value_ = _Start();
-
- _LIBCPP_HIDE_FROM_ABI
- __iota_view_iterator() requires default_initializable<_Start> = default;
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr explicit __iota_view_iterator(_Start __value) : __value_(std::move(__value)) {}
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
- return __value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iota_view_iterator& operator++() {
- ++__value_;
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr void operator++(int) { ++*this; }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iota_view_iterator operator++(int) requires incrementable<_Start> {
- auto __tmp = *this;
- ++*this;
- return __tmp;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iota_view_iterator& operator--() requires __decrementable<_Start> {
- --__value_;
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iota_view_iterator operator--(int) requires __decrementable<_Start> {
- auto __tmp = *this;
- --*this;
- return __tmp;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iota_view_iterator& operator+=(difference_type __n)
- requires __advanceable<_Start>
- {
- if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
- if (__n >= difference_type(0)) {
- __value_ += static_cast<_Start>(__n);
- } else {
- __value_ -= static_cast<_Start>(-__n);
- }
- } else {
- __value_ += __n;
- }
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iota_view_iterator& operator-=(difference_type __n)
- requires __advanceable<_Start>
- {
- if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
- if (__n >= difference_type(0)) {
- __value_ -= static_cast<_Start>(__n);
- } else {
- __value_ += static_cast<_Start>(-__n);
- }
- } else {
- __value_ -= __n;
- }
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr _Start operator[](difference_type __n) const
- requires __advanceable<_Start>
- {
- return _Start(__value_ + __n);
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
- requires equality_comparable<_Start>
- {
- return __x.__value_ == __y.__value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
- requires totally_ordered<_Start>
- {
- return __x.__value_ < __y.__value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
- requires totally_ordered<_Start>
- {
- return __y < __x;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<=(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
- requires totally_ordered<_Start>
- {
- return !(__y < __x);
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>=(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
- requires totally_ordered<_Start>
- {
- return !(__x < __y);
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr auto operator<=>(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
- requires totally_ordered<_Start> && three_way_comparable<_Start>
- {
- return __x.__value_ <=> __y.__value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr __iota_view_iterator operator+(__iota_view_iterator __i, difference_type __n)
- requires __advanceable<_Start>
- {
- __i += __n;
- return __i;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr __iota_view_iterator operator+(difference_type __n, __iota_view_iterator __i)
- requires __advanceable<_Start>
- {
- return __i + __n;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr __iota_view_iterator operator-(__iota_view_iterator __i, difference_type __n)
- requires __advanceable<_Start>
- {
- __i -= __n;
- return __i;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr difference_type operator-(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
- requires __advanceable<_Start>
- {
- if constexpr (__integer_like<_Start>) {
- if constexpr (__signed_integer_like<_Start>) {
- return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
- }
- if (__y.__value_ > __x.__value_) {
- return difference_type(-difference_type(__y.__value_ - __x.__value_));
- }
- return difference_type(__x.__value_ - __y.__value_);
- }
- return __x.__value_ - __y.__value_;
- }
- };
-
- template <weakly_incrementable _Start, semiregular _BoundSentinel>
- requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
- struct __iota_view_sentinel {
-
- template <weakly_incrementable _StartT, semiregular _BoundSentinelT>
- requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT>
- friend class iota_view;
-
- using __iterator = __iota_view_iterator<_Start>;
-
- private:
- _BoundSentinel __bound_sentinel_ = _BoundSentinel();
-
- public:
- _LIBCPP_HIDE_FROM_ABI
- __iota_view_sentinel() = default;
- constexpr explicit __iota_view_sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator& __x, const __iota_view_sentinel& __y) {
- return __x.__value_ == __y.__bound_sentinel_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __iota_view_sentinel& __y)
- requires sized_sentinel_for<_BoundSentinel, _Start>
- {
- return __x.__value_ - __y.__bound_sentinel_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr iter_difference_t<_Start> operator-(const __iota_view_sentinel& __x, const __iterator& __y)
- requires sized_sentinel_for<_BoundSentinel, _Start>
- {
- return -(__y - __x);
- }
- };
-
namespace views {
namespace __iota {
struct __fn {
diff --git a/libcxx/include/__ranges/istream_view.h b/libcxx/include/__ranges/istream_view.h
index 69a9df35a4d2..66cd91527616 100644
--- a/libcxx/include/__ranges/istream_view.h
+++ b/libcxx/include/__ranges/istream_view.h
@@ -36,18 +36,10 @@ namespace ranges {
template <class _Val, class _CharT, class _Traits>
concept __stream_extractable = requires(basic_istream<_CharT, _Traits>& __is, _Val& __t) { __is >> __t; };
-template <movable _Val, class _CharT, class _Traits>
- requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
-class __basic_istream_view_iterator;
-
template <movable _Val, class _CharT, class _Traits = char_traits<_CharT>>
requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
class basic_istream_view : public view_interface<basic_istream_view<_Val, _CharT, _Traits>> {
- using __iterator = __basic_istream_view_iterator<_Val, _CharT, _Traits>;
-
- template <movable _ValueType, class _CharType, class _TraitsType>
- requires default_initializable<_ValueType> && __stream_extractable<_ValueType, _CharType, _TraitsType>
- friend class __basic_istream_view_iterator;
+ class __iterator;
public:
_LIBCPP_HIDE_FROM_ABI constexpr explicit basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
@@ -67,23 +59,23 @@ private:
template <movable _Val, class _CharT, class _Traits>
requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
-class __basic_istream_view_iterator {
+class basic_istream_view<_Val, _CharT, _Traits>::__iterator {
public:
using iterator_concept = input_iterator_tag;
using difference_type = ptrdiff_t;
using value_type = _Val;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __basic_istream_view_iterator(
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(
basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept
: __parent_(std::addressof(__parent)) {}
- __basic_istream_view_iterator(const __basic_istream_view_iterator&) = delete;
- _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator(__basic_istream_view_iterator&&) = default;
+ __iterator(const __iterator&) = delete;
+ _LIBCPP_HIDE_FROM_ABI __iterator(__iterator&&) = default;
- __basic_istream_view_iterator& operator=(const __basic_istream_view_iterator&) = delete;
- _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator& operator=(__basic_istream_view_iterator&&) = default;
+ __iterator& operator=(const __iterator&) = delete;
+ _LIBCPP_HIDE_FROM_ABI __iterator& operator=(__iterator&&) = default;
- _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator& operator++() {
+ _LIBCPP_HIDE_FROM_ABI __iterator& operator++() {
*__parent_->__stream_ >> __parent_->__value_;
return *this;
}
@@ -92,7 +84,7 @@ public:
_LIBCPP_HIDE_FROM_ABI _Val& operator*() const { return __parent_->__value_; }
- _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __basic_istream_view_iterator& __x, default_sentinel_t) {
+ _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __iterator& __x, default_sentinel_t) {
return !*__x.__get_parent_stream();
}
diff --git a/libcxx/include/__ranges/join_view.h b/libcxx/include/__ranges/join_view.h
index 9d56e13b8439..7c078422e900 100644
--- a/libcxx/include/__ranges/join_view.h
+++ b/libcxx/include/__ranges/join_view.h
@@ -69,14 +69,6 @@ namespace ranges {
>;
};
- template <input_range _View, bool _Const>
- requires view<_View> && input_range<range_reference_t<_View>>
- struct __join_view_iterator;
-
- template <input_range _View, bool _Const>
- requires view<_View> && input_range<range_reference_t<_View>>
- struct __join_view_sentinel;
-
template<input_range _View>
requires view<_View> && input_range<range_reference_t<_View>>
class join_view
@@ -84,19 +76,9 @@ namespace ranges {
private:
using _InnerRange = range_reference_t<_View>;
- template<bool _Const>
- using __iterator = __join_view_iterator<_View, _Const>;
-
- template<bool _Const>
- using __sentinel = __join_view_sentinel<_View, _Const>;
+ template<bool> struct __iterator;
- template <input_range _View2, bool _Const2>
- requires view<_View2> && input_range<range_reference_t<_View2>>
- friend struct __join_view_iterator;
-
- template <input_range _View2, bool _Const2>
- requires view<_View2> && input_range<range_reference_t<_View2>>
- friend struct __join_view_sentinel;
+ template<bool> struct __sentinel;
template <class>
friend struct std::__segmented_iterator_traits;
@@ -167,12 +149,12 @@ namespace ranges {
}
};
- template<input_range _View, bool _Const>
+ template<input_range _View>
requires view<_View> && input_range<range_reference_t<_View>>
- struct __join_view_sentinel {
- template<input_range _View2, bool>
- requires view<_View2> && input_range<range_reference_t<_View2>>
- friend struct __join_view_sentinel;
+ template<bool _Const>
+ struct join_view<_View>::__sentinel {
+ template<bool>
+ friend struct __sentinel;
private:
using _Parent = __maybe_const<_Const, join_view<_View>>;
@@ -181,37 +163,42 @@ namespace ranges {
public:
_LIBCPP_HIDE_FROM_ABI
- __join_view_sentinel() = default;
+ __sentinel() = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit __join_view_sentinel(_Parent& __parent)
+ constexpr explicit __sentinel(_Parent& __parent)
: __end_(ranges::end(__parent.__base_)) {}
_LIBCPP_HIDE_FROM_ABI
- constexpr __join_view_sentinel(__join_view_sentinel<_View, !_Const> __s)
+ constexpr __sentinel(__sentinel<!_Const> __s)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__s.__end_)) {}
template<bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __join_view_iterator<_View, _OtherConst>& __x, const __join_view_sentinel& __y) {
+ friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __x.__outer_ == __y.__end_;
}
};
- template<input_range _View, bool _Const>
+ // https://reviews.llvm.org/D142811#inline-1383022
+ // To simplify the segmented iterator traits specialization,
+ // make the iterator `final`
+ template<input_range _View>
requires view<_View> && input_range<range_reference_t<_View>>
- struct __join_view_iterator
+ template<bool _Const>
+ struct join_view<_View>::__iterator final
: public __join_view_iterator_category<__maybe_const<_Const, _View>> {
- template<input_range _View2, bool>
- requires view<_View2> && input_range<range_reference_t<_View2>>
- friend struct __join_view_iterator;
+ template<bool>
+ friend struct __iterator;
template <class>
friend struct std::__segmented_iterator_traits;
+ static constexpr bool __is_join_view_iterator = true;
+
private:
using _Parent = __maybe_const<_Const, join_view<_View>>;
using _Base = __maybe_const<_Const, _View>;
@@ -246,7 +233,7 @@ namespace ranges {
__inner_.reset();
}
- _LIBCPP_HIDE_FROM_ABI constexpr __join_view_iterator(_Parent* __parent, _Outer __outer, _Inner __inner)
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent* __parent, _Outer __outer, _Inner __inner)
: __outer_(std::move(__outer)), __inner_(std::move(__inner)), __parent_(__parent) {}
public:
@@ -267,17 +254,17 @@ namespace ranges {
range_difference_t<_Base>, range_difference_t<range_reference_t<_Base>>>;
_LIBCPP_HIDE_FROM_ABI
- __join_view_iterator() requires default_initializable<_Outer> = default;
+ __iterator() requires default_initializable<_Outer> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr __join_view_iterator(_Parent& __parent, _Outer __outer)
+ constexpr __iterator(_Parent& __parent, _Outer __outer)
: __outer_(std::move(__outer))
, __parent_(std::addressof(__parent)) {
__satisfy();
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __join_view_iterator(__join_view_iterator<_View, !_Const> __i)
+ constexpr __iterator(__iterator<!_Const> __i)
requires _Const &&
convertible_to<iterator_t<_View>, _Outer> &&
convertible_to<iterator_t<_InnerRange>, _Inner>
@@ -298,7 +285,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __join_view_iterator& operator++() {
+ constexpr __iterator& operator++() {
auto&& __inner = [&]() -> auto&& {
if constexpr (__ref_is_glvalue)
return *__outer_;
@@ -318,7 +305,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __join_view_iterator operator++(int)
+ constexpr __iterator operator++(int)
requires __ref_is_glvalue &&
forward_range<_Base> &&
forward_range<range_reference_t<_Base>>
@@ -329,7 +316,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __join_view_iterator& operator--()
+ constexpr __iterator& operator--()
requires __ref_is_glvalue &&
bidirectional_range<_Base> &&
bidirectional_range<range_reference_t<_Base>> &&
@@ -348,7 +335,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __join_view_iterator operator--(int)
+ constexpr __iterator operator--(int)
requires __ref_is_glvalue &&
bidirectional_range<_Base> &&
bidirectional_range<range_reference_t<_Base>> &&
@@ -360,7 +347,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __join_view_iterator& __x, const __join_view_iterator& __y)
+ friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
requires __ref_is_glvalue &&
equality_comparable<iterator_t<_Base>> &&
equality_comparable<iterator_t<range_reference_t<_Base>>>
@@ -369,14 +356,14 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr decltype(auto) iter_move(const __join_view_iterator& __i)
+ friend constexpr decltype(auto) iter_move(const __iterator& __i)
noexcept(noexcept(ranges::iter_move(*__i.__inner_)))
{
return ranges::iter_move(*__i.__inner_);
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr void iter_swap(const __join_view_iterator& __x, const __join_view_iterator& __y)
+ friend constexpr void iter_swap(const __iterator& __x, const __iterator& __y)
noexcept(noexcept(ranges::iter_swap(*__x.__inner_, *__y.__inner_)))
requires indirectly_swappable<_Inner>
{
@@ -404,12 +391,12 @@ inline namespace __cpo {
} // namespace views
} // namespace ranges
-template <class _View, bool _Const>
- requires(ranges::common_range<typename ranges::__join_view_iterator<_View, _Const>::_Parent> &&
- __is_cpp17_random_access_iterator<typename ranges::__join_view_iterator<_View, _Const>::_Outer>::value &&
- __is_cpp17_random_access_iterator<typename ranges::__join_view_iterator<_View, _Const>::_Inner>::value)
-struct __segmented_iterator_traits<ranges::__join_view_iterator<_View, _Const>> {
- using _JoinViewIterator = ranges::__join_view_iterator<_View, _Const>;
+template <class _JoinViewIterator>
+ requires(_JoinViewIterator::__is_join_view_iterator &&
+ ranges::common_range<typename _JoinViewIterator::_Parent> &&
+ __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Outer>::value &&
+ __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Inner>::value)
+struct __segmented_iterator_traits<_JoinViewIterator> {
using __segment_iterator =
_LIBCPP_NODEBUG __iterator_with_data<typename _JoinViewIterator::_Outer, typename _JoinViewIterator::_Parent*>;
diff --git a/libcxx/include/__ranges/split_view.h b/libcxx/include/__ranges/split_view.h
index 9758ee935f29..6ebe5a43ed22 100644
--- a/libcxx/include/__ranges/split_view.h
+++ b/libcxx/include/__ranges/split_view.h
@@ -42,12 +42,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
-template <class _View, class _Pattern>
-struct __split_view_iterator;
-
-template <class _View, class _Pattern>
-struct __split_view_sentinel;
-
template <forward_range _View, forward_range _Pattern>
requires view<_View> && view<_Pattern> &&
indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
@@ -59,13 +53,13 @@ private:
_Cache __cached_begin_ = _Cache();
template <class, class>
- friend struct __split_view_iterator;
+ friend struct __iterator;
template <class, class>
- friend struct __split_view_sentinel;
+ friend struct __sentinel;
- using __iterator = __split_view_iterator<_View, _Pattern>;
- using __sentinel = __split_view_sentinel<_View, _Pattern>;
+ struct __iterator;
+ struct __sentinel;
_LIBCPP_HIDE_FROM_ABI constexpr subrange<iterator_t<_View>> __find_next(iterator_t<_View> __it) {
auto [__begin, __end] = ranges::search(subrange(__it, ranges::end(__base_)), __pattern_);
@@ -120,16 +114,17 @@ split_view(_Range&&, _Pattern&&) -> split_view<views::all_t<_Range>, views::all_
template <forward_range _Range>
split_view(_Range&&, range_value_t<_Range>) -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
-template <class _View, class _Pattern>
-struct __split_view_iterator {
+template <forward_range _View, forward_range _Pattern>
+ requires view<_View> && view<_Pattern> &&
+ indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
+struct split_view<_View, _Pattern>::__iterator {
private:
- split_view<_View, _Pattern>* __parent_ = nullptr;
+ split_view* __parent_ = nullptr;
_LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __cur_ = iterator_t<_View>();
_LIBCPP_NO_UNIQUE_ADDRESS subrange<iterator_t<_View>> __next_ = subrange<iterator_t<_View>>();
bool __trailing_empty_ = false;
- template <class, class>
- friend struct __split_view_sentinel;
+ friend struct __sentinel;
public:
using iterator_concept = forward_iterator_tag;
@@ -137,9 +132,9 @@ public:
using value_type = subrange<iterator_t<_View>>;
using difference_type = range_difference_t<_View>;
- _LIBCPP_HIDE_FROM_ABI __split_view_iterator() = default;
+ _LIBCPP_HIDE_FROM_ABI __iterator() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator(
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(
split_view<_View, _Pattern>& __parent, iterator_t<_View> __current, subrange<iterator_t<_View>> __next)
: __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {}
@@ -147,7 +142,7 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { return {__cur_, __next_.begin()}; }
- _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator& operator++() {
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
__cur_ = __next_.begin();
if (__cur_ != ranges::end(__parent_->__base_)) {
__cur_ = __next_.end();
@@ -163,36 +158,35 @@ public:
return *this;
}
- _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator operator++(int) {
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
auto __tmp = *this;
++*this;
return __tmp;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator==(const __split_view_iterator& __x, const __split_view_iterator& __y) {
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
return __x.__cur_ == __y.__cur_ && __x.__trailing_empty_ == __y.__trailing_empty_;
}
};
-template <class _View, class _Pattern>
-struct __split_view_sentinel {
+template <forward_range _View, forward_range _Pattern>
+ requires view<_View> && view<_Pattern> &&
+ indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
+struct split_view<_View, _Pattern>::__sentinel {
private:
_LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_View> __end_ = sentinel_t<_View>();
- _LIBCPP_HIDE_FROM_ABI static constexpr bool
- __equals(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) {
+ _LIBCPP_HIDE_FROM_ABI static constexpr bool __equals(const __iterator& __x, const __sentinel& __y) {
return __x.__cur_ == __y.__end_ && !__x.__trailing_empty_;
}
public:
- _LIBCPP_HIDE_FROM_ABI __split_view_sentinel() = default;
+ _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __split_view_sentinel(split_view<_View, _Pattern>& __parent)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(split_view<_View, _Pattern>& __parent)
: __end_(ranges::end(__parent.__base_)) {}
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator==(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) {
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
return __equals(__x, __y);
}
};
diff --git a/libcxx/include/__ranges/take_while_view.h b/libcxx/include/__ranges/take_while_view.h
index 59c0a4f82889..77d7390dceb9 100644
--- a/libcxx/include/__ranges/take_while_view.h
+++ b/libcxx/include/__ranges/take_while_view.h
@@ -53,17 +53,11 @@ template <class _View, class _Pred>
concept __take_while_const_is_range =
range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>>;
-template <class, class, bool>
-class __take_while_view_sentinel;
-
template <view _View, class _Pred>
requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
class take_while_view : public view_interface<take_while_view<_View, _Pred>> {
- template <class, class, bool>
- friend class __take_while_view_sentinel;
-
- template <bool _Const>
- using __sentinel = __take_while_view_sentinel<_View, _Pred, _Const>;
+ template <bool>
+ class __sentinel;
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
_LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
@@ -114,37 +108,37 @@ public:
template <class _Range, class _Pred>
take_while_view(_Range&&, _Pred) -> take_while_view<views::all_t<_Range>, _Pred>;
-template <class _View, class _Pred, bool _Const>
-class __take_while_view_sentinel {
+template <view _View, class _Pred>
+ requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
+template <bool _Const>
+class take_while_view<_View, _Pred>::__sentinel {
using _Base = __maybe_const<_Const, _View>;
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
const _Pred* __pred_ = nullptr;
- template <class, class, bool>
- friend class __take_while_view_sentinel;
+ friend class __sentinel<!_Const>;
public:
- _LIBCPP_HIDE_FROM_ABI __take_while_view_sentinel() = default;
+ _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __take_while_view_sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
: __end_(std::move(__end)), __pred_(__pred) {}
- _LIBCPP_HIDE_FROM_ABI constexpr __take_while_view_sentinel(__take_while_view_sentinel<_View, _Pred, !_Const> __s)
+ _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__s.__end_)), __pred_(__s.__pred_) {}
_LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator==(const iterator_t<_Base>& __x, const __take_while_view_sentinel& __y) {
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const iterator_t<_Base>& __x, const __sentinel& __y) {
return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x);
}
template <bool _OtherConst = !_Const>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __take_while_view_sentinel& __y) {
+ operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __sentinel& __y) {
return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x);
}
};
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index 66d9e80e6e61..0b5ced3df428 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -57,31 +57,11 @@ concept __transform_view_constraints =
regular_invocable<_Fn&, range_reference_t<_View>> &&
__can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>;
-template <input_range _View, copy_constructible _Function, bool _IsConst>
- requires __transform_view_constraints<_View, _Function>
-class __transform_view_iterator;
-
-template <input_range _View, copy_constructible _Function, bool _IsConst>
- requires __transform_view_constraints<_View, _Function>
-class __transform_view_sentinel;
-
template<input_range _View, copy_constructible _Fn>
requires __transform_view_constraints<_View, _Fn>
class transform_view : public view_interface<transform_view<_View, _Fn>> {
-
- template <bool _IsConst>
- using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>;
-
- template <bool _IsConst>
- using __sentinel = __transform_view_sentinel<_View, _Fn, _IsConst>;
-
- template <input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
- requires __transform_view_constraints<_ViewType, _FunctionType>
- friend class __transform_view_iterator;
-
- template <input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
- requires __transform_view_constraints<_ViewType, _FunctionType>
- friend class __transform_view_sentinel;
+ template<bool> class __iterator;
+ template<bool> class __sentinel;
_LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_;
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
@@ -176,23 +156,22 @@ struct __transform_view_iterator_category_base<_View, _Fn> {
>;
};
-template<input_range _View, copy_constructible _Fn, bool _Const>
+template<input_range _View, copy_constructible _Fn>
requires __transform_view_constraints<_View, _Fn>
-class __transform_view_iterator
+template<bool _Const>
+class transform_view<_View, _Fn>::__iterator
: public __transform_view_iterator_category_base<_View, _Fn> {
- using _Parent = __maybe_const<_Const, transform_view<_View, _Fn>>;
+ using _Parent = __maybe_const<_Const, transform_view>;
using _Base = __maybe_const<_Const, _View>;
_Parent *__parent_ = nullptr;
- template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
- requires __transform_view_constraints<_ViewType, _FunctionType>
- friend class __transform_view_iterator;
+ template<bool>
+ friend class transform_view<_View, _Fn>::__iterator;
- template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
- requires __transform_view_constraints<_ViewType, _FunctionType>
- friend class __transform_view_sentinel;
+ template<bool>
+ friend class transform_view<_View, _Fn>::__sentinel;
public:
iterator_t<_Base> __current_ = iterator_t<_Base>();
@@ -202,17 +181,17 @@ public:
using difference_type = range_difference_t<_Base>;
_LIBCPP_HIDE_FROM_ABI
- __transform_view_iterator() requires default_initializable<iterator_t<_Base>> = default;
+ __iterator() requires default_initializable<iterator_t<_Base>> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr __transform_view_iterator(_Parent& __parent, iterator_t<_Base> __current)
+ constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
: __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
- // Note: `__i` should always be `__transform_view_iterator<false>`, but directly using
- // `__transform_view_iterator<false>` is ill-formed when `_Const` is false
+ // Note: `__i` should always be `__iterator<false>`, but directly using
+ // `__iterator<false>` is ill-formed when `_Const` is false
// (see http://wg21.link/class.copy.ctor#5).
_LIBCPP_HIDE_FROM_ABI
- constexpr __transform_view_iterator(__transform_view_iterator<_View, _Fn, !_Const> __i)
+ constexpr __iterator(__iterator<!_Const> __i)
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
: __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
@@ -234,7 +213,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __transform_view_iterator& operator++() {
+ constexpr __iterator& operator++() {
++__current_;
return *this;
}
@@ -243,7 +222,7 @@ public:
constexpr void operator++(int) { ++__current_; }
_LIBCPP_HIDE_FROM_ABI
- constexpr __transform_view_iterator operator++(int)
+ constexpr __iterator operator++(int)
requires forward_range<_Base>
{
auto __tmp = *this;
@@ -252,7 +231,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __transform_view_iterator& operator--()
+ constexpr __iterator& operator--()
requires bidirectional_range<_Base>
{
--__current_;
@@ -260,7 +239,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __transform_view_iterator operator--(int)
+ constexpr __iterator operator--(int)
requires bidirectional_range<_Base>
{
auto __tmp = *this;
@@ -269,7 +248,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __transform_view_iterator& operator+=(difference_type __n)
+ constexpr __iterator& operator+=(difference_type __n)
requires random_access_range<_Base>
{
__current_ += __n;
@@ -277,7 +256,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __transform_view_iterator& operator-=(difference_type __n)
+ constexpr __iterator& operator-=(difference_type __n)
requires random_access_range<_Base>
{
__current_ -= __n;
@@ -293,77 +272,77 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+ friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
requires equality_comparable<iterator_t<_Base>>
{
return __x.__current_ == __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+ friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ < __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+ friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ > __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<=(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+ friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ <= __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>=(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+ friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ >= __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr auto operator<=>(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+ friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
{
return __x.__current_ <=> __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr __transform_view_iterator operator+(__transform_view_iterator __i, difference_type __n)
+ friend constexpr __iterator operator+(__iterator __i, difference_type __n)
requires random_access_range<_Base>
{
- return __transform_view_iterator{*__i.__parent_, __i.__current_ + __n};
+ return __iterator{*__i.__parent_, __i.__current_ + __n};
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr __transform_view_iterator operator+(difference_type __n, __transform_view_iterator __i)
+ friend constexpr __iterator operator+(difference_type __n, __iterator __i)
requires random_access_range<_Base>
{
- return __transform_view_iterator{*__i.__parent_, __i.__current_ + __n};
+ return __iterator{*__i.__parent_, __i.__current_ + __n};
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr __transform_view_iterator operator-(__transform_view_iterator __i, difference_type __n)
+ friend constexpr __iterator operator-(__iterator __i, difference_type __n)
requires random_access_range<_Base>
{
- return __transform_view_iterator{*__i.__parent_, __i.__current_ - __n};
+ return __iterator{*__i.__parent_, __i.__current_ - __n};
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr difference_type operator-(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
+ friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
{
return __x.__current_ - __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr decltype(auto) iter_move(const __transform_view_iterator& __i)
+ friend constexpr decltype(auto) iter_move(const __iterator& __i)
noexcept(noexcept(*__i))
{
if constexpr (is_lvalue_reference_v<decltype(*__i)>)
@@ -373,37 +352,33 @@ public:
}
};
-template<input_range _View, copy_constructible _Fn, bool _Const>
+template<input_range _View, copy_constructible _Fn>
requires __transform_view_constraints<_View, _Fn>
-class __transform_view_sentinel {
- using _Parent = __maybe_const<_Const, transform_view<_View, _Fn>>;
+template<bool _Const>
+class transform_view<_View, _Fn>::__sentinel {
+ using _Parent = __maybe_const<_Const, transform_view>;
using _Base = __maybe_const<_Const, _View>;
- template <bool _IsConst>
- using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>;
-
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
- template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
- requires __transform_view_constraints<_ViewType, _FunctionType>
- friend class __transform_view_iterator;
+ template<bool>
+ friend class transform_view<_View, _Fn>::__iterator;
- template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
- requires __transform_view_constraints<_ViewType, _FunctionType>
- friend class __transform_view_sentinel;
+ template<bool>
+ friend class transform_view<_View, _Fn>::__sentinel;
public:
_LIBCPP_HIDE_FROM_ABI
- __transform_view_sentinel() = default;
+ __sentinel() = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit __transform_view_sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
+ constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
- // Note: `__i` should always be `__transform_view_sentinel<false>`, but directly using
- // `__transform_view_sentinel<false>` is ill-formed when `_Const` is false
+ // Note: `__i` should always be `__sentinel<false>`, but directly using
+ // `__sentinel<false>` is ill-formed when `_Const` is false
// (see http://wg21.link/class.copy.ctor#5).
_LIBCPP_HIDE_FROM_ABI
- constexpr __transform_view_sentinel(__transform_view_sentinel<_View, _Fn, !_Const> __i)
+ constexpr __sentinel(__sentinel<!_Const> __i)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__i.__end_)) {}
@@ -413,7 +388,7 @@ public:
template<bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __transform_view_sentinel& __y) {
+ friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __x.__current_ == __y.__end_;
}
@@ -421,7 +396,7 @@ public:
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI
friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
- operator-(const __iterator<_OtherConst>& __x, const __transform_view_sentinel& __y) {
+ operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
return __x.__current_ - __y.__end_;
}
@@ -429,7 +404,7 @@ public:
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI
friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
- operator-(const __transform_view_sentinel& __x, const __iterator<_OtherConst>& __y) {
+ operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
return __x.__end_ - __y.__current_;
}
};
diff --git a/libcxx/include/__type_traits/add_pointer.h b/libcxx/include/__type_traits/add_pointer.h
index 9d0c2010077b..1af5eca65c63 100644
--- a/libcxx/include/__type_traits/add_pointer.h
+++ b/libcxx/include/__type_traits/add_pointer.h
@@ -22,7 +22,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_builtin(__add_pointer)
+#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
template <class _Tp>
using __add_pointer_t = __add_pointer(_Tp);
@@ -39,7 +39,7 @@ template <class _Tp> struct __add_pointer_impl<_Tp, false>
template <class _Tp>
using __add_pointer_t = typename __add_pointer_impl<_Tp>::type;
-#endif // __has_builtin(__add_pointer)
+#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
template <class _Tp>
struct add_pointer {
diff --git a/libcxx/include/__type_traits/remove_pointer.h b/libcxx/include/__type_traits/remove_pointer.h
index 33ddb7103f0d..2f810ba666bb 100644
--- a/libcxx/include/__type_traits/remove_pointer.h
+++ b/libcxx/include/__type_traits/remove_pointer.h
@@ -17,7 +17,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_builtin(__remove_pointer)
+#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer)
template <class _Tp>
struct remove_pointer {
using type _LIBCPP_NODEBUG = __remove_pointer(_Tp);
@@ -34,7 +34,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volat
template <class _Tp>
using __remove_pointer_t = typename remove_pointer<_Tp>::type;
-#endif // __has_builtin(__remove_pointer)
+#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer)
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_pointer_t = __remove_pointer_t<_Tp>;
diff --git a/libcxx/include/any b/libcxx/include/any
index 92cbc9a6c92d..50a44d7f4d70 100644
--- a/libcxx/include/any
+++ b/libcxx/include/any
@@ -175,7 +175,7 @@ namespace __any_imp
inline _LIBCPP_INLINE_VISIBILITY
bool __compare_typeid(type_info const* __id, const void* __fallback_id)
{
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
if (__id && *__id == typeid(_Tp))
return true;
#endif
@@ -294,7 +294,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
bool has_value() const _NOEXCEPT { return __h_ != nullptr; }
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
_LIBCPP_INLINE_VISIBILITY
const type_info & type() const _NOEXCEPT {
if (__h_) {
@@ -426,7 +426,7 @@ namespace __any_imp
_LIBCPP_INLINE_VISIBILITY
static void* __type_info()
{
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
#else
return nullptr;
@@ -514,7 +514,7 @@ namespace __any_imp
_LIBCPP_INLINE_VISIBILITY
static void* __type_info()
{
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
#else
return nullptr;
@@ -680,7 +680,7 @@ any_cast(any * __any) _NOEXCEPT
typedef add_pointer_t<_ValueType> _ReturnType;
if (__any && __any->__h_) {
void *__p = __any->__call(_Action::_Get, nullptr,
-#if !defined(_LIBCPP_NO_RTTI)
+#if !defined(_LIBCPP_HAS_NO_RTTI)
&typeid(_ValueType),
#else
nullptr,
diff --git a/libcxx/include/version b/libcxx/include/version
index 9705229a1c52..28c4a50cdab7 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -139,6 +139,7 @@ __cpp_lib_polymorphic_allocator 201902L <memory_resource
__cpp_lib_quoted_string_io 201304L <iomanip>
__cpp_lib_ranges 202106L <algorithm> <functional> <iterator>
<memory> <ranges>
+__cpp_lib_ranges_as_rvalue 202207L <ranges>
__cpp_lib_ranges_chunk 202202L <ranges>
__cpp_lib_ranges_chunk_by 202202L <ranges>
__cpp_lib_ranges_iota 202202L <numeric>
@@ -401,6 +402,7 @@ __cpp_lib_void_t 201411L <type_traits>
# undef __cpp_lib_optional
# define __cpp_lib_optional 202110L
// # define __cpp_lib_out_ptr 202106L
+# define __cpp_lib_ranges_as_rvalue 202207L
// # define __cpp_lib_ranges_chunk 202202L
// # define __cpp_lib_ranges_chunk_by 202202L
// # define __cpp_lib_ranges_iota 202202L
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 6c478ad4109b..87887b314a5a 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -846,9 +846,7 @@ public:
static void mergeArch(RISCVISAInfo::OrderedExtensionMap &mergedExts,
unsigned &mergedXlen, const InputSectionBase *sec,
StringRef s) {
- auto maybeInfo =
- RISCVISAInfo::parseArchString(s, /*EnableExperimentalExtension=*/true,
- /*ExperimentalExtensionVersionCheck=*/true);
+ auto maybeInfo = RISCVISAInfo::parseNormalizedArchString(s);
if (!maybeInfo) {
errorOrWarn(toString(sec) + ": " + s + ": " +
llvm::toString(maybeInfo.takeError()));
@@ -863,8 +861,6 @@ static void mergeArch(RISCVISAInfo::OrderedExtensionMap &mergedExts,
} else {
for (const auto &ext : info.getExtensions()) {
if (auto it = mergedExts.find(ext.first); it != mergedExts.end()) {
- // TODO This is untested because RISCVISAInfo::parseArchString does not
- // accept unsupported versions yet.
if (std::tie(it->second.MajorVersion, it->second.MinorVersion) >=
std::tie(ext.second.MajorVersion, ext.second.MinorVersion))
continue;
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index d7a85bcf844f..c2b0ce9b12b9 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -323,8 +323,9 @@ bool ICF<ELFT>::equalsConstant(const InputSection *a, const InputSection *b) {
const RelsOrRelas<ELFT> ra = a->template relsOrRelas<ELFT>();
const RelsOrRelas<ELFT> rb = b->template relsOrRelas<ELFT>();
- return ra.areRelocsRel() ? constantEq(a, ra.rels, b, rb.rels)
- : constantEq(a, ra.relas, b, rb.relas);
+ return ra.areRelocsRel() || rb.areRelocsRel()
+ ? constantEq(a, ra.rels, b, rb.rels)
+ : constantEq(a, ra.relas, b, rb.relas);
}
// Compare two lists of relocations. Returns true if all pairs of
@@ -371,8 +372,9 @@ template <class ELFT>
bool ICF<ELFT>::equalsVariable(const InputSection *a, const InputSection *b) {
const RelsOrRelas<ELFT> ra = a->template relsOrRelas<ELFT>();
const RelsOrRelas<ELFT> rb = b->template relsOrRelas<ELFT>();
- return ra.areRelocsRel() ? variableEq(a, ra.rels, b, rb.rels)
- : variableEq(a, ra.relas, b, rb.relas);
+ return ra.areRelocsRel() || rb.areRelocsRel()
+ ? variableEq(a, ra.rels, b, rb.rels)
+ : variableEq(a, ra.relas, b, rb.relas);
}
template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t begin, size_t end) {
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index f09d0d7f9095..f616245233b1 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -277,8 +277,8 @@ void SymbolTable::scanVersionScript() {
pat.isExternCpp, /*hasWildCard=*/false},
id, ver, /*includeNonDefault=*/true);
if (!found && !config->undefinedVersion)
- errorOrWarn("version script assignment of '" + ver + "' to symbol '" +
- pat.name + "' failed: symbol not defined");
+ warn("version script assignment of '" + ver + "' to symbol '" +
+ pat.name + "' failed: symbol not defined");
};
for (SymbolVersion &pat : v.nonLocalPatterns)
if (!pat.hasWildcard)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index bd9ff99db67b..c5170757496f 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -8,7 +8,6 @@
#include "Coroutines.h"
-#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/VariableList.h"
@@ -17,38 +16,37 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-static ValueObjectSP GetCoroFramePtrFromHandle(ValueObject &valobj) {
- ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+static lldb::addr_t GetCoroFramePtrFromHandle(ValueObjectSP valobj_sp) {
if (!valobj_sp)
- return nullptr;
+ return LLDB_INVALID_ADDRESS;
// We expect a single pointer in the `coroutine_handle` class.
// We don't care about its name.
if (valobj_sp->GetNumChildren() != 1)
- return nullptr;
+ return LLDB_INVALID_ADDRESS;
ValueObjectSP ptr_sp(valobj_sp->GetChildAtIndex(0, true));
if (!ptr_sp)
- return nullptr;
+ return LLDB_INVALID_ADDRESS;
if (!ptr_sp->GetCompilerType().IsPointerType())
- return nullptr;
-
- return ptr_sp;
-}
-
-static Function *ExtractDestroyFunction(ValueObjectSP &frame_ptr_sp) {
- lldb::TargetSP target_sp = frame_ptr_sp->GetTargetSP();
- lldb::ProcessSP process_sp = frame_ptr_sp->GetProcessSP();
- auto ptr_size = process_sp->GetAddressByteSize();
+ return LLDB_INVALID_ADDRESS;
AddressType addr_type;
- lldb::addr_t frame_ptr_addr = frame_ptr_sp->GetPointerValue(&addr_type);
+ lldb::addr_t frame_ptr_addr = ptr_sp->GetPointerValue(&addr_type);
if (!frame_ptr_addr || frame_ptr_addr == LLDB_INVALID_ADDRESS)
- return nullptr;
+ return LLDB_INVALID_ADDRESS;
lldbassert(addr_type == AddressType::eAddressTypeLoad);
+ if (addr_type != AddressType::eAddressTypeLoad)
+ return LLDB_INVALID_ADDRESS;
+
+ return frame_ptr_addr;
+}
+
+static Function *ExtractDestroyFunction(lldb::TargetSP target_sp,
+ lldb::addr_t frame_ptr_addr) {
+ lldb::ProcessSP process_sp = target_sp->GetProcessSP();
+ auto ptr_size = process_sp->GetAddressByteSize();
Status error;
- // The destroy pointer is the 2nd pointer inside the compiler-generated
- // `pair<resumePtr,destroyPtr>`.
auto destroy_func_ptr_addr = frame_ptr_addr + ptr_size;
lldb::addr_t destroy_func_addr =
process_sp->ReadPointerFromMemory(destroy_func_ptr_addr, error);
@@ -59,12 +57,7 @@ static Function *ExtractDestroyFunction(ValueObjectSP &frame_ptr_sp) {
if (!target_sp->ResolveLoadAddress(destroy_func_addr, destroy_func_address))
return nullptr;
- Function *destroy_func =
- destroy_func_address.CalculateSymbolContextFunction();
- if (!destroy_func)
- return nullptr;
-
- return destroy_func;
+ return destroy_func_address.CalculateSymbolContextFunction();
}
static CompilerType InferPromiseType(Function &destroy_func) {
@@ -85,44 +78,25 @@ static CompilerType InferPromiseType(Function &destroy_func) {
return promise_type->GetForwardCompilerType();
}
-static CompilerType GetCoroutineFrameType(TypeSystemClang &ast_ctx,
- CompilerType promise_type) {
- CompilerType void_type = ast_ctx.GetBasicType(lldb::eBasicTypeVoid);
- CompilerType coro_func_type = ast_ctx.CreateFunctionType(
- /*result_type=*/void_type, /*args=*/&void_type, /*num_args=*/1,
- /*is_variadic=*/false, /*qualifiers=*/0);
- CompilerType coro_abi_type;
- if (promise_type.IsVoidType()) {
- coro_abi_type = ast_ctx.CreateStructForIdentifier(
- ConstString(), {{"resume", coro_func_type.GetPointerType()},
- {"destroy", coro_func_type.GetPointerType()}});
- } else {
- coro_abi_type = ast_ctx.CreateStructForIdentifier(
- ConstString(), {{"resume", coro_func_type.GetPointerType()},
- {"destroy", coro_func_type.GetPointerType()},
- {"promise", promise_type}});
- }
- return coro_abi_type;
-}
-
bool lldb_private::formatters::StdlibCoroutineHandleSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
- ValueObjectSP ptr_sp(GetCoroFramePtrFromHandle(valobj));
- if (!ptr_sp)
+ lldb::addr_t frame_ptr_addr =
+ GetCoroFramePtrFromHandle(valobj.GetNonSyntheticValue());
+ if (frame_ptr_addr == LLDB_INVALID_ADDRESS)
return false;
- if (!ptr_sp->GetValueAsUnsigned(0)) {
+ if (frame_ptr_addr == 0) {
stream << "nullptr";
} else {
- stream.Printf("coro frame = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
+ stream.Printf("coro frame = 0x%" PRIx64, frame_ptr_addr);
}
+
return true;
}
lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
StdlibCoroutineHandleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp),
- m_ast_importer(std::make_unique<ClangASTImporter>()) {
+ : SyntheticChildrenFrontEnd(*valobj_sp) {
if (valobj_sp)
Update();
}
@@ -132,32 +106,61 @@ lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
size_t lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
CalculateNumChildren() {
- if (!m_frame_ptr_sp)
+ if (!m_resume_ptr_sp || !m_destroy_ptr_sp)
return 0;
- return m_frame_ptr_sp->GetNumChildren();
+ return m_promise_ptr_sp ? 3 : 2;
}
lldb::ValueObjectSP lldb_private::formatters::
StdlibCoroutineHandleSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
- if (!m_frame_ptr_sp)
- return lldb::ValueObjectSP();
-
- return m_frame_ptr_sp->GetChildAtIndex(idx, true);
+ switch (idx) {
+ case 0:
+ return m_resume_ptr_sp;
+ case 1:
+ return m_destroy_ptr_sp;
+ case 2:
+ return m_promise_ptr_sp;
+ }
+ return lldb::ValueObjectSP();
}
bool lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
Update() {
- m_frame_ptr_sp.reset();
+ m_resume_ptr_sp.reset();
+ m_destroy_ptr_sp.reset();
+ m_promise_ptr_sp.reset();
- ValueObjectSP valobj_sp = m_backend.GetSP();
+ ValueObjectSP valobj_sp = m_backend.GetNonSyntheticValue();
if (!valobj_sp)
return false;
- ValueObjectSP ptr_sp(GetCoroFramePtrFromHandle(m_backend));
- if (!ptr_sp)
+ lldb::addr_t frame_ptr_addr = GetCoroFramePtrFromHandle(valobj_sp);
+ if (frame_ptr_addr == 0 || frame_ptr_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ auto ts = valobj_sp->GetCompilerType().GetTypeSystem();
+ auto ast_ctx = ts.dyn_cast_or_null<TypeSystemClang>();
+ if (!ast_ctx)
return false;
+ // Create the `resume` and `destroy` children.
+ lldb::TargetSP target_sp = m_backend.GetTargetSP();
+ auto &exe_ctx = m_backend.GetExecutionContextRef();
+ lldb::ProcessSP process_sp = target_sp->GetProcessSP();
+ auto ptr_size = process_sp->GetAddressByteSize();
+ CompilerType void_type = ast_ctx->GetBasicType(lldb::eBasicTypeVoid);
+ CompilerType coro_func_type = ast_ctx->CreateFunctionType(
+ /*result_type=*/void_type, /*args=*/&void_type, /*num_args=*/1,
+ /*is_variadic=*/false, /*qualifiers=*/0);
+ CompilerType coro_func_ptr_type = coro_func_type.GetPointerType();
+ m_resume_ptr_sp = CreateValueObjectFromAddress(
+ "resume", frame_ptr_addr + 0 * ptr_size, exe_ctx, coro_func_ptr_type);
+ lldbassert(m_resume_ptr_sp);
+ m_destroy_ptr_sp = CreateValueObjectFromAddress(
+ "destroy", frame_ptr_addr + 1 * ptr_size, exe_ctx, coro_func_ptr_type);
+ lldbassert(m_destroy_ptr_sp);
+
// Get the `promise_type` from the template argument
CompilerType promise_type(
valobj_sp->GetCompilerType().GetTypeTemplateArgument(0));
@@ -165,23 +168,31 @@ bool lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
return false;
// Try to infer the promise_type if it was type-erased
- auto ts = valobj_sp->GetCompilerType().GetTypeSystem();
- auto ast_ctx = ts.dyn_cast_or_null<TypeSystemClang>();
- if (!ast_ctx)
- return false;
if (promise_type.IsVoidType()) {
- if (Function *destroy_func = ExtractDestroyFunction(ptr_sp)) {
+ if (Function *destroy_func =
+ ExtractDestroyFunction(target_sp, frame_ptr_addr)) {
if (CompilerType inferred_type = InferPromiseType(*destroy_func)) {
- // Copy the type over to the correct `TypeSystemClang` instance
- promise_type = m_ast_importer->CopyType(*ast_ctx, inferred_type);
+ promise_type = inferred_type;
}
}
}
- // Build the coroutine frame type
- CompilerType coro_frame_type = GetCoroutineFrameType(*ast_ctx, promise_type);
+ // If we don't know the promise type, we don't display the `promise` member.
+ // `CreateValueObjectFromAddress` below would fail for `void` types.
+ if (promise_type.IsVoidType()) {
+ return false;
+ }
- m_frame_ptr_sp = ptr_sp->Cast(coro_frame_type.GetPointerType());
+ // Add the `promise` member. We intentionally add `promise` as a pointer type
+ // instead of a value type, and don't automatically dereference this pointer.
+ // We do so to avoid potential very deep recursion in case there is a cycle
+ // formed between `std::coroutine_handle`s and their promises.
+ lldb::ValueObjectSP promise = CreateValueObjectFromAddress(
+ "promise", frame_ptr_addr + 2 * ptr_size, exe_ctx, promise_type);
+ Status error;
+ lldb::ValueObjectSP promisePtr = promise->AddressOf(error);
+ if (error.Success())
+ m_promise_ptr_sp = promisePtr->Clone(ConstString("promise"));
return false;
}
@@ -193,10 +204,17 @@ bool lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
size_t StdlibCoroutineHandleSyntheticFrontEnd::GetIndexOfChildWithName(
ConstString name) {
- if (!m_frame_ptr_sp)
+ if (!m_resume_ptr_sp || !m_destroy_ptr_sp)
return UINT32_MAX;
- return m_frame_ptr_sp->GetIndexOfChildWithName(name);
+ if (name == ConstString("resume"))
+ return 0;
+ if (name == ConstString("destroy"))
+ return 1;
+ if (name == ConstString("promise_ptr") && m_promise_ptr_sp)
+ return 2;
+
+ return UINT32_MAX;
}
SyntheticChildrenFrontEnd *
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.h b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.h
index c052bd23f4ca..b26cc9ed6132 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.h
@@ -16,8 +16,6 @@
namespace lldb_private {
-class ClangASTImporter;
-
namespace formatters {
/// Summary provider for `std::coroutine_handle<T>` from libc++, libstdc++ and
@@ -47,8 +45,9 @@ public:
size_t GetIndexOfChildWithName(ConstString name) override;
private:
- lldb::ValueObjectSP m_frame_ptr_sp;
- std::unique_ptr<lldb_private::ClangASTImporter> m_ast_importer;
+ lldb::ValueObjectSP m_resume_ptr_sp;
+ lldb::ValueObjectSP m_destroy_ptr_sp;
+ lldb::ValueObjectSP m_promise_ptr_sp;
};
SyntheticChildrenFrontEnd *
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index c4bd0fa3e07c..51b67d1756b9 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -1297,10 +1297,17 @@ public:
bool loopIsFiniteByAssumption(const Loop *L);
class FoldID {
- SmallVector<unsigned, 4> Bits;
+ SmallVector<unsigned, 5> Bits;
public:
- void addInteger(unsigned long I) { Bits.push_back(I); }
+ void addInteger(unsigned long I) {
+ if (sizeof(long) == sizeof(int))
+ addInteger(unsigned(I));
+ else if (sizeof(long) == sizeof(long long))
+ addInteger((unsigned long long)I);
+ else
+ llvm_unreachable("unexpected sizeof(long)");
+ }
void addInteger(unsigned I) { Bits.push_back(I); }
void addInteger(int I) { Bits.push_back(I); }
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
index 2603c4542e8d..68dfefba3b3c 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
@@ -15,7 +15,6 @@
#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVELEMENT_H
#include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
-#include "llvm/DebugInfo/LogicalView/Core/LVStringPool.h"
#include "llvm/Support/Casting.h"
#include <map>
#include <set>
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVStringPool.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVStringPool.h
index 671ccf5d0e15..4c596b5b1dde 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVStringPool.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVStringPool.h
@@ -71,11 +71,6 @@ public:
return (Index >= Entries.size()) ? StringRef() : Entries[Index]->getKey();
}
- static LVStringPool &getInstance() {
- static LVStringPool Instance;
- return Instance;
- }
-
void print(raw_ostream &OS) const {
if (!Entries.empty()) {
OS << "\nString Pool:\n";
@@ -90,8 +85,6 @@ public:
#endif
};
-inline LVStringPool &getStringPool() { return LVStringPool::getInstance(); }
-
} // namespace logicalview
} // end namespace llvm
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
index bff1499c1a60..a2274ec1a62f 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/DebugInfo/LogicalView/Core/LVStringPool.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
@@ -27,6 +28,9 @@
namespace llvm {
namespace logicalview {
+// Returns the unique string pool instance.
+LVStringPool &getStringPool();
+
template <typename T>
using TypeIsValid = std::bool_constant<std::is_pointer<T>::value>;
diff --git a/llvm/include/llvm/Support/ExitCodes.h b/llvm/include/llvm/Support/ExitCodes.h
index b9041f5557d5..4eb5dedc688b 100644
--- a/llvm/include/llvm/Support/ExitCodes.h
+++ b/llvm/include/llvm/Support/ExitCodes.h
@@ -20,9 +20,9 @@
#if HAVE_SYSEXITS_H
#include <sysexits.h>
-#elif __MVS__
-// <sysexits.h> does not exist on z/OS. The only value used in LLVM is
-// EX_IOERR, which is used to signal a special error condition (broken pipe).
+#elif __MVS__ || defined(_WIN32)
+// <sysexits.h> does not exist on z/OS and Windows. The only value used in LLVM
+// is EX_IOERR, which is used to signal a special error condition (broken pipe).
// Define the macro with its usual value from BSD systems, which is chosen to
// not clash with more standard exit codes like 1.
#define EX_IOERR 74
diff --git a/llvm/include/llvm/Support/RISCVISAInfo.h b/llvm/include/llvm/Support/RISCVISAInfo.h
index 9070b88d710e..219435979698 100644
--- a/llvm/include/llvm/Support/RISCVISAInfo.h
+++ b/llvm/include/llvm/Support/RISCVISAInfo.h
@@ -51,6 +51,12 @@ public:
bool ExperimentalExtensionVersionCheck = true,
bool IgnoreUnknown = false);
+ /// Parse RISCV ISA info from an arch string that is already in normalized
+ /// form (as defined in the psABI). Unlike parseArchString, this function
+ /// will not error for unrecognized extension names or extension versions.
+ static llvm::Expected<std::unique_ptr<RISCVISAInfo>>
+ parseNormalizedArchString(StringRef Arch);
+
/// Parse RISCV ISA info from feature vector.
static llvm::Expected<std::unique_ptr<RISCVISAInfo>>
parseFeatures(unsigned XLen, const std::vector<std::string> &Features);
diff --git a/llvm/include/llvm/Support/Signals.h b/llvm/include/llvm/Support/Signals.h
index 937e0572d4a7..70749ce30184 100644
--- a/llvm/include/llvm/Support/Signals.h
+++ b/llvm/include/llvm/Support/Signals.h
@@ -102,14 +102,17 @@ namespace sys {
/// functions. A null handler pointer disables the current installed
/// function. Note also that the handler may be executed on a
/// different thread on some platforms.
- ///
- /// This is a no-op on Windows.
void SetOneShotPipeSignalFunction(void (*Handler)());
- /// On Unix systems, this function exits with an "IO error" exit code.
- /// This is a no-op on Windows.
+ /// On Unix systems and Windows, this function exits with an "IO error" exit
+ /// code.
void DefaultOneShotPipeSignalHandler();
+#ifdef _WIN32
+ /// Windows does not support signals and this handler must be called manually.
+ void CallOneShotPipeSignalHandler();
+#endif
+
/// This function does the following:
/// - clean up any temporary files registered with RemoveFileOnSignal()
/// - dump the callstack from the exception context
diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index da2ecd8c1339..f50576b8fee1 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -18,6 +18,9 @@
#include <vector>
namespace llvm {
+
+class Triple;
+
namespace RISCV {
// We use 64 bits as the known part in the scalable vector types.
@@ -38,6 +41,8 @@ void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
bool getCPUFeaturesExceptStdExt(CPUKind Kind, std::vector<StringRef> &Features);
+bool isX18ReservedByDefault(const Triple &TT);
+
} // namespace RISCV
} // namespace llvm
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 8d600989c8cf..59513fa2f206 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -882,6 +882,14 @@ public:
return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;
}
+ /// Tests whether the target 64-bit PowerPC big endian ABI is ELFv2.
+ bool isPPC64ELFv2ABI() const {
+ return (getArch() == Triple::ppc64 &&
+ ((getOS() == Triple::FreeBSD &&
+ (getOSMajorVersion() >= 13 || getOSVersion().empty())) ||
+ getOS() == Triple::OpenBSD || isMusl()));
+ }
+
/// Tests whether the target is 32-bit RISC-V.
bool isRISCV32() const { return getArch() == Triple::riscv32; }
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index f1587cecf9fb..0e9fab667e6e 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1673,11 +1673,6 @@ ConstantRange LazyValueInfo::getConstantRangeAtUse(const Use &U,
// TODO: Use non-local query?
CondVal =
getEdgeValueLocal(V, PHI->getIncomingBlock(*CurrU), PHI->getParent());
- } else if (!isSafeToSpeculativelyExecute(CurrI)) {
- // Stop walking if we hit a non-speculatable instruction. Even if the
- // result is only used under a specific condition, executing the
- // instruction itself may cause side effects or UB already.
- break;
}
if (CondVal && CondVal->isConstantRange())
CR = CR.intersectWith(CondVal->getConstantRange());
@@ -1685,7 +1680,13 @@ ConstantRange LazyValueInfo::getConstantRangeAtUse(const Use &U,
// Only follow one-use chain, to allow direct intersection of conditions.
// If there are multiple uses, we would have to intersect with the union of
// all conditions at different uses.
- if (!CurrI->hasOneUse())
+ // Stop walking if we hit a non-speculatable instruction. Even if the
+ // result is only used under a specific condition, executing the
+ // instruction itself may cause side effects or UB already.
+ // This also disallows looking through phi nodes: If the phi node is part
+ // of a cycle, we might end up reasoning about values from different cycle
+ // iterations (PR60629).
+ if (!CurrI->hasOneUse() || !isSafeToSpeculativelyExecute(CurrI))
break;
CurrU = &*CurrI->use_begin();
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 0a3ebd73d272..eed3d820c120 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -10447,7 +10447,8 @@ SDValue DAGCombiner::combineMinNumMaxNum(const SDLoc &DL, EVT VT, SDValue LHS,
if (NegRHS == False) {
SDValue Combined = combineMinNumMaxNumImpl(DL, VT, LHS, RHS, NegTrue,
False, CC, TLI, DAG);
- return DAG.getNode(ISD::FNEG, DL, VT, Combined);
+ if (Combined)
+ return DAG.getNode(ISD::FNEG, DL, VT, Combined);
}
}
}
@@ -12453,7 +12454,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) {
SDValue N00 = N0.getOperand(0);
EVT ExtVT = cast<VTSDNode>(N0->getOperand(1))->getVT();
- if (N00.getOpcode() == ISD::TRUNCATE && (!LegalOperations || TLI.isTypeLegal(ExtVT))) {
+ if (N00.getOpcode() == ISD::TRUNCATE &&
+ (!LegalTypes || TLI.isTypeLegal(ExtVT))) {
SDValue T = DAG.getNode(ISD::TRUNCATE, DL, ExtVT, N00.getOperand(0));
return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, T);
}
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index da8b87babc2d..abd3273509ce 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -724,7 +724,9 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) {
// with the Target-specific changes necessary.
MaxAtomicSizeInBitsSupported = 1024;
- MaxDivRemBitWidthSupported = llvm::IntegerType::MAX_INT_BITS;
+ // Assume that even with libcalls, no target supports wider than 128 bit
+ // division.
+ MaxDivRemBitWidthSupported = 128;
MaxLargeFPConvertBitWidthSupported = llvm::IntegerType::MAX_INT_BITS;
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVSupport.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVSupport.cpp
index 9fa1f28eb089..6d55b755ed46 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVSupport.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVSupport.cpp
@@ -20,6 +20,12 @@ using namespace llvm::logicalview;
#define DEBUG_TYPE "Support"
+namespace {
+// Unique string pool instance used by all logical readers.
+LVStringPool StringPool;
+} // namespace
+LVStringPool &llvm::logicalview::getStringPool() { return StringPool; }
+
// Perform the following transformations to the given 'Path':
// - all characters to lowercase.
// - '\\' into '/' (Platform independent).
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 72c008d9835e..a92dfbcc5c64 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -649,22 +649,29 @@ namespace {
// vectorcall - foo@@12
// These are all different linkage names for 'foo'.
StringRef demanglePE32ExternCFunc(StringRef SymbolName) {
- // Remove any '_' or '@' prefix.
char Front = SymbolName.empty() ? '\0' : SymbolName[0];
- if (Front == '_' || Front == '@')
- SymbolName = SymbolName.drop_front();
// Remove any '@[0-9]+' suffix.
+ bool HasAtNumSuffix = false;
if (Front != '?') {
size_t AtPos = SymbolName.rfind('@');
if (AtPos != StringRef::npos &&
- all_of(drop_begin(SymbolName, AtPos + 1), isDigit))
+ all_of(drop_begin(SymbolName, AtPos + 1), isDigit)) {
SymbolName = SymbolName.substr(0, AtPos);
+ HasAtNumSuffix = true;
+ }
}
// Remove any ending '@' for vectorcall.
- if (SymbolName.endswith("@"))
+ bool IsVectorCall = false;
+ if (HasAtNumSuffix && SymbolName.endswith("@")) {
SymbolName = SymbolName.drop_back();
+ IsVectorCall = true;
+ }
+
+ // If not vectorcall, remove any '_' or '@' prefix.
+ if (!IsVectorCall && (Front == '_' || Front == '@'))
+ SymbolName = SymbolName.drop_front();
return SymbolName;
}
@@ -692,8 +699,14 @@ LLVMSymbolizer::DemangleName(const std::string &Name,
return Result;
}
- if (DbiModuleDescriptor && DbiModuleDescriptor->isWin32Module())
- return std::string(demanglePE32ExternCFunc(Name));
+ if (DbiModuleDescriptor && DbiModuleDescriptor->isWin32Module()) {
+ std::string DemangledCName(demanglePE32ExternCFunc(Name));
+ // On i386 Windows, the C name mangling for different calling conventions
+ // may also be applied on top of the Itanium or Rust name mangling.
+ if (nonMicrosoftDemangle(DemangledCName.c_str(), Result))
+ return Result;
+ return DemangledCName;
+ }
return Name;
}
diff --git a/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_unix.S b/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_unix.S
index 449e07492832..69fc0936d73c 100644
--- a/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_unix.S
+++ b/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_unix.S
@@ -1,5 +1,7 @@
#if defined(__x86_64__)
+#include "llvm_blake3_prefix.h"
+
#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",%progbits
#endif
diff --git a/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_gnu.S b/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_gnu.S
index bb58d2ae64b1..5ad1c641a7fc 100644
--- a/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_gnu.S
+++ b/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_gnu.S
@@ -1,3 +1,5 @@
+#include "llvm_blake3_prefix.h"
+
.intel_syntax noprefix
.global _blake3_hash_many_avx2
.global blake3_hash_many_avx2
diff --git a/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_msvc.asm b/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_msvc.asm
index 352298edd2e8..46bad1d98f38 100644
--- a/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_msvc.asm
+++ b/llvm/lib/Support/BLAKE3/blake3_avx2_x86-64_windows_msvc.asm
@@ -1,11 +1,11 @@
-public _blake3_hash_many_avx2
-public blake3_hash_many_avx2
+public _llvm_blake3_hash_many_avx2
+public llvm_blake3_hash_many_avx2
_TEXT SEGMENT ALIGN(16) 'CODE'
ALIGN 16
-blake3_hash_many_avx2 PROC
-_blake3_hash_many_avx2 PROC
+llvm_blake3_hash_many_avx2 PROC
+_llvm_blake3_hash_many_avx2 PROC
push r15
push r14
push r13
@@ -1785,8 +1785,8 @@ endroundloop1:
vmovdqu xmmword ptr [rbx+10H], xmm1
jmp unwind
-_blake3_hash_many_avx2 ENDP
-blake3_hash_many_avx2 ENDP
+_llvm_blake3_hash_many_avx2 ENDP
+llvm_blake3_hash_many_avx2 ENDP
_TEXT ENDS
_RDATA SEGMENT READONLY PAGE ALIAS(".rdata") 'CONST'
diff --git a/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_unix.S b/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_unix.S
index 3afc0e2250e2..f04a135dd1bc 100644
--- a/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_unix.S
+++ b/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_unix.S
@@ -1,5 +1,7 @@
#if defined(__x86_64__)
+#include "llvm_blake3_prefix.h"
+
#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",%progbits
#endif
diff --git a/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_gnu.S b/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_gnu.S
index e10b9f36cbcc..53c586141fbe 100644
--- a/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_gnu.S
+++ b/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_gnu.S
@@ -1,3 +1,5 @@
+#include "llvm_blake3_prefix.h"
+
.intel_syntax noprefix
.global _blake3_hash_many_avx512
diff --git a/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_msvc.asm b/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_msvc.asm
index b19efbaaeb36..f13d1b260ab8 100644
--- a/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_msvc.asm
+++ b/llvm/lib/Support/BLAKE3/blake3_avx512_x86-64_windows_msvc.asm
@@ -1,15 +1,15 @@
-public _blake3_hash_many_avx512
-public blake3_hash_many_avx512
-public blake3_compress_in_place_avx512
-public _blake3_compress_in_place_avx512
-public blake3_compress_xof_avx512
-public _blake3_compress_xof_avx512
+public _llvm_blake3_hash_many_avx512
+public llvm_blake3_hash_many_avx512
+public llvm_blake3_compress_in_place_avx512
+public _llvm_blake3_compress_in_place_avx512
+public llvm_blake3_compress_xof_avx512
+public _llvm_blake3_compress_xof_avx512
_TEXT SEGMENT ALIGN(16) 'CODE'
ALIGN 16
-blake3_hash_many_avx512 PROC
-_blake3_hash_many_avx512 PROC
+llvm_blake3_hash_many_avx512 PROC
+_llvm_blake3_hash_many_avx512 PROC
push r15
push r14
push r13
@@ -2404,12 +2404,12 @@ endroundloop1:
vmovdqu xmmword ptr [rbx+10H], xmm1
jmp unwind
-_blake3_hash_many_avx512 ENDP
-blake3_hash_many_avx512 ENDP
+_llvm_blake3_hash_many_avx512 ENDP
+llvm_blake3_hash_many_avx512 ENDP
ALIGN 16
-blake3_compress_in_place_avx512 PROC
-_blake3_compress_in_place_avx512 PROC
+llvm_blake3_compress_in_place_avx512 PROC
+_llvm_blake3_compress_in_place_avx512 PROC
sub rsp, 72
vmovdqa xmmword ptr [rsp], xmm6
vmovdqa xmmword ptr [rsp+10H], xmm7
@@ -2498,12 +2498,12 @@ _blake3_compress_in_place_avx512 PROC
vmovdqa xmm9, xmmword ptr [rsp+30H]
add rsp, 72
ret
-_blake3_compress_in_place_avx512 ENDP
-blake3_compress_in_place_avx512 ENDP
+_llvm_blake3_compress_in_place_avx512 ENDP
+llvm_blake3_compress_in_place_avx512 ENDP
ALIGN 16
-blake3_compress_xof_avx512 PROC
-_blake3_compress_xof_avx512 PROC
+llvm_blake3_compress_xof_avx512 PROC
+_llvm_blake3_compress_xof_avx512 PROC
sub rsp, 72
vmovdqa xmmword ptr [rsp], xmm6
vmovdqa xmmword ptr [rsp+10H], xmm7
@@ -2597,8 +2597,8 @@ _blake3_compress_xof_avx512 PROC
vmovdqa xmm9, xmmword ptr [rsp+30H]
add rsp, 72
ret
-_blake3_compress_xof_avx512 ENDP
-blake3_compress_xof_avx512 ENDP
+_llvm_blake3_compress_xof_avx512 ENDP
+llvm_blake3_compress_xof_avx512 ENDP
_TEXT ENDS
diff --git a/llvm/lib/Support/BLAKE3/blake3_impl.h b/llvm/lib/Support/BLAKE3/blake3_impl.h
index 180d0a6eeda8..8e5456d745cd 100644
--- a/llvm/lib/Support/BLAKE3/blake3_impl.h
+++ b/llvm/lib/Support/BLAKE3/blake3_impl.h
@@ -11,15 +11,7 @@
// For \p LLVM_LIBRARY_VISIBILITY
#include "llvm/Support/Compiler.h"
-// Remove the 'llvm_' prefix for the rest of the internal implementation.
-#define BLAKE3_VERSION_STRING LLVM_BLAKE3_VERSION_STRING
-#define BLAKE3_KEY_LEN LLVM_BLAKE3_KEY_LEN
-#define BLAKE3_OUT_LEN LLVM_BLAKE3_OUT_LEN
-#define BLAKE3_BLOCK_LEN LLVM_BLAKE3_BLOCK_LEN
-#define BLAKE3_CHUNK_LEN LLVM_BLAKE3_CHUNK_LEN
-#define BLAKE3_MAX_DEPTH LLVM_BLAKE3_MAX_DEPTH
-#define blake3_hasher llvm_blake3_hasher
-#define blake3_chunk_state llvm_blake3_chunk_state
+#include "llvm_blake3_prefix.h"
// internal flags
enum blake3_flags {
diff --git a/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_unix.S b/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_unix.S
index 0106b13ba851..9a4f5eb7318b 100644
--- a/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_unix.S
+++ b/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_unix.S
@@ -1,5 +1,7 @@
#if defined(__x86_64__)
+#include "llvm_blake3_prefix.h"
+
#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",%progbits
#endif
diff --git a/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_gnu.S b/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_gnu.S
index 8852ba5976e1..bf3b4523a9f1 100644
--- a/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_gnu.S
+++ b/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_gnu.S
@@ -1,3 +1,5 @@
+#include "llvm_blake3_prefix.h"
+
.intel_syntax noprefix
.global blake3_hash_many_sse2
.global _blake3_hash_many_sse2
diff --git a/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_msvc.asm b/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_msvc.asm
index 507502f11a80..1069c8df4ed6 100644
--- a/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_msvc.asm
+++ b/llvm/lib/Support/BLAKE3/blake3_sse2_x86-64_windows_msvc.asm
@@ -1,15 +1,15 @@
-public _blake3_hash_many_sse2
-public blake3_hash_many_sse2
-public blake3_compress_in_place_sse2
-public _blake3_compress_in_place_sse2
-public blake3_compress_xof_sse2
-public _blake3_compress_xof_sse2
+public _llvm_blake3_hash_many_sse2
+public llvm_blake3_hash_many_sse2
+public llvm_blake3_compress_in_place_sse2
+public _llvm_blake3_compress_in_place_sse2
+public llvm_blake3_compress_xof_sse2
+public _llvm_blake3_compress_xof_sse2
_TEXT SEGMENT ALIGN(16) 'CODE'
ALIGN 16
-blake3_hash_many_sse2 PROC
-_blake3_hash_many_sse2 PROC
+llvm_blake3_hash_many_sse2 PROC
+_llvm_blake3_hash_many_sse2 PROC
push r15
push r14
push r13
@@ -2034,11 +2034,11 @@ endroundloop1:
movups xmmword ptr [rbx], xmm0
movups xmmword ptr [rbx+10H], xmm1
jmp unwind
-_blake3_hash_many_sse2 ENDP
-blake3_hash_many_sse2 ENDP
+_llvm_blake3_hash_many_sse2 ENDP
+llvm_blake3_hash_many_sse2 ENDP
-blake3_compress_in_place_sse2 PROC
-_blake3_compress_in_place_sse2 PROC
+llvm_blake3_compress_in_place_sse2 PROC
+_llvm_blake3_compress_in_place_sse2 PROC
sub rsp, 120
movdqa xmmword ptr [rsp], xmm6
movdqa xmmword ptr [rsp+10H], xmm7
@@ -2164,12 +2164,12 @@ _blake3_compress_in_place_sse2 PROC
movdqa xmm15, xmmword ptr [rsp+60H]
add rsp, 120
ret
-_blake3_compress_in_place_sse2 ENDP
-blake3_compress_in_place_sse2 ENDP
+_llvm_blake3_compress_in_place_sse2 ENDP
+llvm_blake3_compress_in_place_sse2 ENDP
ALIGN 16
-blake3_compress_xof_sse2 PROC
-_blake3_compress_xof_sse2 PROC
+llvm_blake3_compress_xof_sse2 PROC
+_llvm_blake3_compress_xof_sse2 PROC
sub rsp, 120
movdqa xmmword ptr [rsp], xmm6
movdqa xmmword ptr [rsp+10H], xmm7
@@ -2302,8 +2302,8 @@ _blake3_compress_xof_sse2 PROC
movdqa xmm15, xmmword ptr [rsp+60H]
add rsp, 120
ret
-_blake3_compress_xof_sse2 ENDP
-blake3_compress_xof_sse2 ENDP
+_llvm_blake3_compress_xof_sse2 ENDP
+llvm_blake3_compress_xof_sse2 ENDP
_TEXT ENDS
diff --git a/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_unix.S b/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_unix.S
index 4e918c5bb2cc..1be4ed744426 100644
--- a/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_unix.S
+++ b/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_unix.S
@@ -1,5 +1,7 @@
#if defined(__x86_64__)
+#include "llvm_blake3_prefix.h"
+
#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",%progbits
#endif
diff --git a/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_gnu.S b/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_gnu.S
index 60d0a4042e71..28bdf3890a29 100644
--- a/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_gnu.S
+++ b/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_gnu.S
@@ -1,3 +1,5 @@
+#include "llvm_blake3_prefix.h"
+
.intel_syntax noprefix
.global blake3_hash_many_sse41
.global _blake3_hash_many_sse41
diff --git a/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_msvc.asm b/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_msvc.asm
index 8966c7b84406..770935372cd9 100644
--- a/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_msvc.asm
+++ b/llvm/lib/Support/BLAKE3/blake3_sse41_x86-64_windows_msvc.asm
@@ -1,15 +1,15 @@
-public _blake3_hash_many_sse41
-public blake3_hash_many_sse41
-public blake3_compress_in_place_sse41
-public _blake3_compress_in_place_sse41
-public blake3_compress_xof_sse41
-public _blake3_compress_xof_sse41
+public _llvm_blake3_hash_many_sse41
+public llvm_blake3_hash_many_sse41
+public llvm_blake3_compress_in_place_sse41
+public _llvm_blake3_compress_in_place_sse41
+public llvm_blake3_compress_xof_sse41
+public _llvm_blake3_compress_xof_sse41
_TEXT SEGMENT ALIGN(16) 'CODE'
ALIGN 16
-blake3_hash_many_sse41 PROC
-_blake3_hash_many_sse41 PROC
+llvm_blake3_hash_many_sse41 PROC
+_llvm_blake3_hash_many_sse41 PROC
push r15
push r14
push r13
@@ -1797,11 +1797,11 @@ endroundloop1:
movups xmmword ptr [rbx], xmm0
movups xmmword ptr [rbx+10H], xmm1
jmp unwind
-_blake3_hash_many_sse41 ENDP
-blake3_hash_many_sse41 ENDP
+_llvm_blake3_hash_many_sse41 ENDP
+llvm_blake3_hash_many_sse41 ENDP
-blake3_compress_in_place_sse41 PROC
-_blake3_compress_in_place_sse41 PROC
+llvm_blake3_compress_in_place_sse41 PROC
+_llvm_blake3_compress_in_place_sse41 PROC
sub rsp, 120
movdqa xmmword ptr [rsp], xmm6
movdqa xmmword ptr [rsp+10H], xmm7
@@ -1916,12 +1916,12 @@ _blake3_compress_in_place_sse41 PROC
movdqa xmm15, xmmword ptr [rsp+60H]
add rsp, 120
ret
-_blake3_compress_in_place_sse41 ENDP
-blake3_compress_in_place_sse41 ENDP
+_llvm_blake3_compress_in_place_sse41 ENDP
+llvm_blake3_compress_in_place_sse41 ENDP
ALIGN 16
-blake3_compress_xof_sse41 PROC
-_blake3_compress_xof_sse41 PROC
+llvm_blake3_compress_xof_sse41 PROC
+_llvm_blake3_compress_xof_sse41 PROC
sub rsp, 120
movdqa xmmword ptr [rsp], xmm6
movdqa xmmword ptr [rsp+10H], xmm7
@@ -2043,8 +2043,8 @@ _blake3_compress_xof_sse41 PROC
movdqa xmm15, xmmword ptr [rsp+60H]
add rsp, 120
ret
-_blake3_compress_xof_sse41 ENDP
-blake3_compress_xof_sse41 ENDP
+_llvm_blake3_compress_xof_sse41 ENDP
+llvm_blake3_compress_xof_sse41 ENDP
_TEXT ENDS
diff --git a/llvm/lib/Support/BLAKE3/llvm_blake3_prefix.h b/llvm/lib/Support/BLAKE3/llvm_blake3_prefix.h
new file mode 100644
index 000000000000..3cee3691e4cf
--- /dev/null
+++ b/llvm/lib/Support/BLAKE3/llvm_blake3_prefix.h
@@ -0,0 +1,41 @@
+#ifndef LLVM_BLAKE3_PREFIX_H
+#define LLVM_BLAKE3_PREFIX_H
+
+#define BLAKE3_VERSION_STRING LLVM_BLAKE3_VERSION_STRING
+#define BLAKE3_KEY_LEN LLVM_BLAKE3_KEY_LEN
+#define BLAKE3_OUT_LEN LLVM_BLAKE3_OUT_LEN
+#define BLAKE3_BLOCK_LEN LLVM_BLAKE3_BLOCK_LEN
+#define BLAKE3_CHUNK_LEN LLVM_BLAKE3_CHUNK_LEN
+#define BLAKE3_MAX_DEPTH LLVM_BLAKE3_MAX_DEPTH
+#define blake3_hasher llvm_blake3_hasher
+#define blake3_chunk_state llvm_blake3_chunk_state
+#define blake3_compress_in_place llvm_blake3_compress_in_place
+#define blake3_compress_xof llvm_blake3_compress_xof
+#define blake3_hash_many llvm_blake3_hash_many
+#define blake3_simd_degree llvm_blake3_simd_degree
+#define blake3_compress_in_place_portable llvm_blake3_compress_in_place_portable
+#define blake3_compress_xof_portable llvm_blake3_compress_xof_portable
+#define blake3_hash_many_portable llvm_blake3_hash_many_portable
+#define blake3_compress_in_place_sse2 llvm_blake3_compress_in_place_sse2
+#define _blake3_compress_in_place_sse2 _llvm_blake3_compress_in_place_sse2
+#define blake3_compress_xof_sse2 llvm_blake3_compress_xof_sse2
+#define _blake3_compress_xof_sse2 _llvm_blake3_compress_xof_sse2
+#define blake3_hash_many_sse2 llvm_blake3_hash_many_sse2
+#define _blake3_hash_many_sse2 _llvm_blake3_hash_many_sse2
+#define blake3_compress_in_place_sse41 llvm_blake3_compress_in_place_sse41
+#define _blake3_compress_in_place_sse41 _llvm_blake3_compress_in_place_sse41
+#define blake3_compress_xof_sse41 llvm_blake3_compress_xof_sse41
+#define _blake3_compress_xof_sse41 _llvm_blake3_compress_xof_sse41
+#define blake3_hash_many_sse41 llvm_blake3_hash_many_sse41
+#define _blake3_hash_many_sse41 _llvm_blake3_hash_many_sse41
+#define blake3_hash_many_avx2 llvm_blake3_hash_many_avx2
+#define _blake3_hash_many_avx2 _llvm_blake3_hash_many_avx2
+#define blake3_compress_in_place_avx512 llvm_blake3_compress_in_place_avx512
+#define _blake3_compress_in_place_avx512 _llvm_blake3_compress_in_place_avx512
+#define blake3_compress_xof_avx512 llvm_blake3_compress_xof_avx512
+#define _blake3_compress_xof_avx512 _llvm_blake3_compress_xof_avx512
+#define blake3_hash_many_avx512 llvm_blake3_hash_many_avx512
+#define _blake3_hash_many_avx512 _llvm_blake3_hash_many_avx512
+#define blake3_hash_many_neon llvm_blake3_hash_many_neon
+
+#endif /* LLVM_BLAKE3_PREFIX_H */
diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index 1b1bff023d2f..b14fe1358d1f 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -503,6 +503,67 @@ RISCVISAInfo::parseFeatures(unsigned XLen,
}
llvm::Expected<std::unique_ptr<RISCVISAInfo>>
+RISCVISAInfo::parseNormalizedArchString(StringRef Arch) {
+ if (llvm::any_of(Arch, isupper)) {
+ return createStringError(errc::invalid_argument,
+ "string must be lowercase");
+ }
+ // Must start with a valid base ISA name.
+ unsigned XLen;
+ if (Arch.startswith("rv32i") || Arch.startswith("rv32e"))
+ XLen = 32;
+ else if (Arch.startswith("rv64i") || Arch.startswith("rv64e"))
+ XLen = 64;
+ else
+ return createStringError(errc::invalid_argument,
+ "arch string must begin with valid base ISA");
+ std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
+ // Discard rv32/rv64 prefix.
+ Arch = Arch.substr(4);
+
+ // Each extension is of the form ${name}${major_version}p${minor_version}
+ // and separated by _. Split by _ and then extract the name and version
+ // information for each extension.
+ SmallVector<StringRef, 8> Split;
+ Arch.split(Split, '_');
+ for (StringRef Ext : Split) {
+ StringRef Prefix, MinorVersionStr;
+ std::tie(Prefix, MinorVersionStr) = Ext.rsplit('p');
+ if (MinorVersionStr.empty())
+ return createStringError(errc::invalid_argument,
+ "extension lacks version in expected format");
+ unsigned MajorVersion, MinorVersion;
+ if (MinorVersionStr.getAsInteger(10, MinorVersion))
+ return createStringError(errc::invalid_argument,
+ "failed to parse minor version number");
+
+ // Split Prefix into the extension name and the major version number
+ // (the trailing digits of Prefix).
+ int TrailingDigits = 0;
+ StringRef ExtName = Prefix;
+ while (!ExtName.empty()) {
+ if (!isDigit(ExtName.back()))
+ break;
+ ExtName = ExtName.drop_back(1);
+ TrailingDigits++;
+ }
+ if (!TrailingDigits)
+ return createStringError(errc::invalid_argument,
+ "extension lacks version in expected format");
+
+ StringRef MajorVersionStr = Prefix.take_back(TrailingDigits);
+ if (MajorVersionStr.getAsInteger(10, MajorVersion))
+ return createStringError(errc::invalid_argument,
+ "failed to parse major version number");
+ ISAInfo->addExtension(ExtName, MajorVersion, MinorVersion);
+ }
+ ISAInfo->updateFLen();
+ ISAInfo->updateMinVLen();
+ ISAInfo->updateMaxELen();
+ return std::move(ISAInfo);
+}
+
+llvm::Expected<std::unique_ptr<RISCVISAInfo>>
RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
bool ExperimentalExtensionVersionCheck,
bool IgnoreUnknown) {
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index 92cf4fcda5a6..7106a67b576a 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -650,8 +650,6 @@ bool equivalent(file_status A, file_status B) {
return A.FileIndexHigh == B.FileIndexHigh &&
A.FileIndexLow == B.FileIndexLow && A.FileSizeHigh == B.FileSizeHigh &&
A.FileSizeLow == B.FileSizeLow &&
- A.LastAccessedTimeHigh == B.LastAccessedTimeHigh &&
- A.LastAccessedTimeLow == B.LastAccessedTimeLow &&
A.LastWriteTimeHigh == B.LastWriteTimeHigh &&
A.LastWriteTimeLow == B.LastWriteTimeLow &&
A.VolumeSerialNumber == B.VolumeSerialNumber;
diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc
index ba93afe0803b..cb82f55fc38b 100644
--- a/llvm/lib/Support/Windows/Signals.inc
+++ b/llvm/lib/Support/Windows/Signals.inc
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/ExitCodes.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
@@ -204,6 +205,9 @@ static bool RegisteredUnhandledExceptionFilter = false;
static bool CleanupExecuted = false;
static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
+/// The function to call on "SIGPIPE" (one-time use only).
+static std::atomic<void (*)()> OneShotPipeSignalFunction(nullptr);
+
// Windows creates a new thread to execute the console handler when an event
// (such as CTRL/C) occurs. This causes concurrency issues with the above
// globals which this critical section addresses.
@@ -575,11 +579,16 @@ void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
}
void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
- // Unimplemented.
+ OneShotPipeSignalFunction.exchange(Handler);
}
void llvm::sys::DefaultOneShotPipeSignalHandler() {
- // Unimplemented.
+ llvm::sys::Process::Exit(EX_IOERR, /*NoCleanup=*/true);
+}
+
+void llvm::sys::CallOneShotPipeSignalHandler() {
+ if (auto OldOneShotPipeFunction = OneShotPipeSignalFunction.exchange(nullptr))
+ OldOneShotPipeFunction();
}
/// Add a function to be called when a signal is delivered to the process. The
@@ -816,7 +825,15 @@ WriteWindowsDumpFile(PMINIDUMP_EXCEPTION_INFORMATION ExceptionInfo) {
}
void sys::CleanupOnSignal(uintptr_t Context) {
- LLVMUnhandledExceptionFilter((LPEXCEPTION_POINTERS)Context);
+ LPEXCEPTION_POINTERS EP = (LPEXCEPTION_POINTERS)Context;
+ // Broken pipe is not a crash.
+ //
+ // 0xE0000000 is combined with the return code in the exception raised in
+ // CrashRecoveryContext::HandleExit().
+ unsigned RetCode = EP->ExceptionRecord->ExceptionCode;
+ if (RetCode == (0xE0000000 | EX_IOERR))
+ return;
+ LLVMUnhandledExceptionFilter(EP);
}
static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
diff --git a/llvm/lib/Support/Z3Solver.cpp b/llvm/lib/Support/Z3Solver.cpp
index a49bedcfd2b0..eb671fe2596d 100644
--- a/llvm/lib/Support/Z3Solver.cpp
+++ b/llvm/lib/Support/Z3Solver.cpp
@@ -729,7 +729,7 @@ public:
const Z3_sort Z3Sort = toZ3Sort(*getBitvectorSort(BitWidth)).Sort;
// Slow path, when 64 bits are not enough.
- if (LLVM_UNLIKELY(Int.getBitWidth() > 64u)) {
+ if (LLVM_UNLIKELY(!Int.isRepresentableByInt64())) {
SmallString<40> Buffer;
Int.toString(Buffer, 10);
return newExprRef(Z3Expr(
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 8943c4478c7f..7b9b8b2f53fb 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -56,6 +56,7 @@
#ifdef _WIN32
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Support/Windows/WindowsSupport.h"
#endif
@@ -775,6 +776,15 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
)
continue;
+#ifdef _WIN32
+ // Windows equivalents of SIGPIPE/EPIPE.
+ DWORD WinLastError = GetLastError();
+ if (WinLastError == ERROR_BROKEN_PIPE ||
+ (WinLastError == ERROR_NO_DATA && errno == EINVAL)) {
+ llvm::sys::CallOneShotPipeSignalHandler();
+ errno = EPIPE;
+ }
+#endif
// Otherwise it's a non-recoverable error. Note it and quit.
error_detected(std::error_code(errno, std::generic_category()));
break;
diff --git a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
index 248bd3130c25..9a2cf94edfe6 100644
--- a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
+++ b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
@@ -71,7 +71,7 @@ static cl::opt<bool> ErrorMissingParenthesis(
static cl::opt<bool> WarnSignedMismatch(
"mwarn-sign-mismatch",
cl::desc("Warn for mismatching a signed and unsigned value"),
- cl::init(true));
+ cl::init(false));
static cl::opt<bool> WarnNoncontigiousRegister(
"mwarn-noncontigious-register",
cl::desc("Warn for register names that arent contigious"), cl::init(true));
diff --git a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
index 9aea5af8a60a..b17e2766a7a1 100644
--- a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -237,7 +237,10 @@ static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT,
case Triple::ppc64le:
return PPCTargetMachine::PPC_ABI_ELFv2;
case Triple::ppc64:
- return PPCTargetMachine::PPC_ABI_ELFv1;
+ if (TT.isPPC64ELFv2ABI())
+ return PPCTargetMachine::PPC_ABI_ELFv2;
+ else
+ return PPCTargetMachine::PPC_ABI_ELFv1;
default:
return PPCTargetMachine::PPC_ABI_UNKNOWN;
}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index a8720d070acb..6eea169f8919 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -14211,6 +14211,25 @@ bool RISCVTargetLowering::preferScalarizeSplat(unsigned Opc) const {
return true;
}
+static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
+ Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+ Function *ThreadPointerFunc =
+ Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
+ return IRB.CreatePointerCast(
+ IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
+ IRB.CreateCall(ThreadPointerFunc), Offset),
+ IRB.getInt8PtrTy()->getPointerTo(0));
+}
+
+Value *RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
+ // Fuchsia provides a fixed TLS slot for the stack cookie.
+ // <zircon/tls.h> defines ZX_TLS_STACK_GUARD_OFFSET with this value.
+ if (Subtarget.isTargetFuchsia())
+ return useTpOffset(IRB, -0x10);
+
+ return TargetLowering::getIRStackGuard(IRB);
+}
+
#define GET_REGISTER_MATCHER
#include "RISCVGenAsmMatcher.inc"
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index acf92cab3598..5086e6c0bdaf 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -618,6 +618,10 @@ public:
return Scale == 1;
}
+ /// If the target has a standard location for the stack protector cookie,
+ /// returns the address of that location. Otherwise, returns nullptr.
+ Value *getIRStackGuard(IRBuilderBase &IRB) const override;
+
private:
/// RISCVCCAssignFn - This target-specific function extends the default
/// CCValAssign with additional information used to lower RISC-V calling
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
index c935dad1687f..d0bb4634d03d 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -83,6 +83,9 @@ RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
FrameLowering(
initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
+ if (RISCV::isX18ReservedByDefault(TT))
+ UserReservedRegister.set(RISCV::X18);
+
CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
Legalizer.reset(new RISCVLegalizerInfo(*this));
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index 678d218a6719..290c7b03ea81 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -176,6 +176,8 @@ public:
const LegalizerInfo *getLegalizerInfo() const override;
const RegisterBankInfo *getRegBankInfo() const override;
+ bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); }
+
bool useConstantPoolForLargeInts() const;
// Maximum cost used for building integers, integers will be put into constant
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index d69e2c3ed493..181de6abb2c5 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -4020,7 +4020,10 @@ bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *N) {
EVT OpVT = ShiftAmt.getValueType();
- NewShiftAmt = CurDAG->getNOT(DL, Add0C == nullptr ? Add0 : Add1, OpVT);
+ SDValue AllOnes = CurDAG->getAllOnesConstant(DL, OpVT);
+ NewShiftAmt = CurDAG->getNode(ISD::XOR, DL, OpVT,
+ Add0C == nullptr ? Add0 : Add1, AllOnes);
+ insertDAGNode(*CurDAG, OrigShiftAmt, AllOnes);
insertDAGNode(*CurDAG, OrigShiftAmt, NewShiftAmt);
// If we are shifting by N-X where N == 0 mod Size, then just shift by
// -X to generate a NEG instead of a SUB of a constant.
diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp
index 89cd5c082d72..933a82b7c6cb 100644
--- a/llvm/lib/TargetParser/RISCVTargetParser.cpp
+++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp
@@ -14,6 +14,7 @@
#include "llvm/TargetParser/RISCVTargetParser.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/TargetParser/Triple.h"
namespace llvm {
namespace RISCV {
@@ -100,5 +101,10 @@ bool getCPUFeaturesExceptStdExt(CPUKind Kind,
return true;
}
+bool isX18ReservedByDefault(const Triple &TT) {
+ // X18 is reserved for the ShadowCallStack ABI (even when not enabled).
+ return TT.isOSFuchsia();
+}
+
} // namespace RISCV
} // namespace llvm
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index b9134ce26e80..84013a8909db 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -396,6 +396,18 @@ static bool getPotentialCopiesOfMemoryValue(
NullOnly = false;
};
+ auto AdjustWrittenValueType = [&](const AAPointerInfo::Access &Acc,
+ Value &V) {
+ Value *AdjV = AA::getWithType(V, *I.getType());
+ if (!AdjV) {
+ LLVM_DEBUG(dbgs() << "Underlying object written but stored value "
+ "cannot be converted to read type: "
+ << *Acc.getRemoteInst() << " : " << *I.getType()
+ << "\n";);
+ }
+ return AdjV;
+ };
+
auto CheckAccess = [&](const AAPointerInfo::Access &Acc, bool IsExact) {
if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))
return true;
@@ -417,7 +429,10 @@ static bool getPotentialCopiesOfMemoryValue(
if (IsLoad) {
assert(isa<LoadInst>(I) && "Expected load or store instruction only!");
if (!Acc.isWrittenValueUnknown()) {
- NewCopies.push_back(Acc.getWrittenValue());
+ Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue());
+ if (!V)
+ return false;
+ NewCopies.push_back(V);
NewCopyOrigins.push_back(Acc.getRemoteInst());
return true;
}
@@ -428,7 +443,10 @@ static bool getPotentialCopiesOfMemoryValue(
<< *Acc.getRemoteInst() << "\n";);
return false;
}
- NewCopies.push_back(SI->getValueOperand());
+ Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand());
+ if (!V)
+ return false;
+ NewCopies.push_back(V);
NewCopyOrigins.push_back(SI);
} else {
assert(isa<StoreInst>(I) && "Expected load or store instruction only!");
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index a28099d8ba7d..148f2c545b41 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -5953,7 +5953,7 @@ LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<ElementCount> VFs) {
// Saves the list of values that are used in the loop but are defined outside
// the loop (not including non-instruction values such as arguments and
// constants).
- SmallPtrSet<Value *, 8> LoopInvariants;
+ SmallPtrSet<Instruction *, 8> LoopInvariants;
for (BasicBlock *BB : make_range(DFS.beginRPO(), DFS.endRPO())) {
for (Instruction &I : BB->instructionsWithoutDebug()) {
@@ -6079,11 +6079,16 @@ LoopVectorizationCostModel::calculateRegisterUsage(ArrayRef<ElementCount> VFs) {
for (auto *Inst : LoopInvariants) {
// FIXME: The target might use more than one register for the type
// even in the scalar case.
- unsigned Usage =
- VFs[i].isScalar() ? 1 : GetRegUsage(Inst->getType(), VFs[i]);
+ bool IsScalar = all_of(Inst->users(), [&](User *U) {
+ auto *I = cast<Instruction>(U);
+ return TheLoop != LI->getLoopFor(I->getParent()) ||
+ isScalarAfterVectorization(I, VFs[i]);
+ });
+
+ ElementCount VF = IsScalar ? ElementCount::getFixed(1) : VFs[i];
unsigned ClassID =
- TTI.getRegisterClassForType(VFs[i].isVector(), Inst->getType());
- Invariant[ClassID] += Usage;
+ TTI.getRegisterClassForType(VF.isVector(), Inst->getType());
+ Invariant[ClassID] += GetRegUsage(Inst->getType(), VF);
}
LLVM_DEBUG({
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index 7366059cd242..7b71d5ad4554 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -635,7 +635,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
"dump-collected-objects", cl::Optional, cl::Hidden,
cl::desc("Show the collected coverage object files"));
- cl::list<std::string> InputSourceFiles(cl::Positional,
+ cl::list<std::string> InputSourceFiles("sources", cl::Positional,
cl::desc("<Source files>"));
cl::opt<bool> DebugDumpCollectedPaths(
diff --git a/openmp/runtime/src/kmp_os.h b/openmp/runtime/src/kmp_os.h
index 1b07dca9031d..c78f3eeaf7cd 100644
--- a/openmp/runtime/src/kmp_os.h
+++ b/openmp/runtime/src/kmp_os.h
@@ -610,7 +610,7 @@ inline kmp_int32 __kmp_compare_and_store_ptr(void *volatile *p, void *cv,
#define KMP_XCHG_FIXED8(p, v) \
_InterlockedExchange8((volatile kmp_int8 *)(p), (kmp_int8)(v));
#define KMP_XCHG_FIXED16(p, v) _InterlockedExchange16((p), (v));
-#define KMP_XCHG_REAL64(p, v) __kmp_xchg_real64((p), (v)));
+#define KMP_XCHG_REAL64(p, v) __kmp_xchg_real64((p), (v));
inline kmp_real64 __kmp_xchg_real64(volatile kmp_real64 *p, kmp_real64 v) {
kmp_int64 tmp = _InterlockedExchange64((volatile kmp_int64 *)p, *(kmp_int64
diff --git a/openmp/runtime/src/kmp_runtime.cpp b/openmp/runtime/src/kmp_runtime.cpp
index 7393dba90b87..88b9e58fca54 100644
--- a/openmp/runtime/src/kmp_runtime.cpp
+++ b/openmp/runtime/src/kmp_runtime.cpp
@@ -24,7 +24,6 @@
#include "kmp_wait_release.h"
#include "kmp_wrapper_getpid.h"
#include "kmp_dispatch.h"
-#include <cstdio>
#if KMP_USE_HIER_SCHED
#include "kmp_dispatch_hier.h"
#endif
@@ -6917,12 +6916,11 @@ void __kmp_unregister_library(void) {
// File did not open. Try the temporary file.
use_shm = false;
KMP_DEBUG_ASSERT(temp_reg_status_file_name);
- FILE *tf = fopen(temp_reg_status_file_name, O_RDONLY);
- if (!tf) {
+ fd1 = open(temp_reg_status_file_name, O_RDONLY);
+ if (fd1 == -1) {
// give it up now.
return;
}
- fd1 = fileno(tf);
}
char *data1 = (char *)mmap(0, SHM_SIZE, PROT_READ, MAP_SHARED, fd1, 0);
if (data1 != MAP_FAILED) {
diff --git a/openmp/runtime/src/kmp_safe_c_api.h b/openmp/runtime/src/kmp_safe_c_api.h
index 3db1ada37b07..72f26fd9897d 100644
--- a/openmp/runtime/src/kmp_safe_c_api.h
+++ b/openmp/runtime/src/kmp_safe_c_api.h
@@ -30,6 +30,7 @@
#define KMP_SSCANF sscanf_s
#define KMP_STRCPY_S strcpy_s
#define KMP_STRNCPY_S strncpy_s
+#define KMP_STRNCAT_S strncat_s
// Use this only when buffer size is unknown
#define KMP_MEMCPY(dst, src, cnt) memcpy_s(dst, cnt, src, cnt)
@@ -61,6 +62,7 @@ template <typename T> struct kmp_get_rmax_t<T, true> {
#define KMP_SSCANF sscanf
#define KMP_STRCPY_S(dst, bsz, src) strcpy(dst, src)
#define KMP_STRNCPY_S(dst, bsz, src, cnt) strncpy(dst, src, cnt)
+#define KMP_STRNCAT_S(dst, bsz, src, cnt) strncat(dst, src, cnt)
#define KMP_VSNPRINTF vsnprintf
#define KMP_STRNCPY strncpy
#define KMP_STRLEN strlen
diff --git a/openmp/runtime/src/kmp_str.cpp b/openmp/runtime/src/kmp_str.cpp
index e64f989fbc69..4cba56964a09 100644
--- a/openmp/runtime/src/kmp_str.cpp
+++ b/openmp/runtime/src/kmp_str.cpp
@@ -137,8 +137,8 @@ void __kmp_str_buf_cat(kmp_str_buf_t *buffer, char const *str, size_t len) {
KMP_DEBUG_ASSERT(len >= 0);
__kmp_str_buf_reserve(buffer, buffer->used + len + 1);
- KMP_MEMCPY(buffer->str + buffer->used, str, len);
- buffer->str[buffer->used + len] = 0;
+ buffer->str[buffer->used] = '\0';
+ KMP_STRNCAT_S(buffer->str + buffer->used, len + 1, str, len);
__kmp_type_convert(buffer->used + len, &(buffer->used));
KMP_STR_BUF_INVARIANT(buffer);
} // __kmp_str_buf_cat
@@ -151,8 +151,8 @@ void __kmp_str_buf_catbuf(kmp_str_buf_t *dest, const kmp_str_buf_t *src) {
if (!src->str || !src->used)
return;
__kmp_str_buf_reserve(dest, dest->used + src->used + 1);
- KMP_MEMCPY(dest->str + dest->used, src->str, src->used);
- dest->str[dest->used + src->used] = 0;
+ dest->str[dest->used] = '\0';
+ KMP_STRNCAT_S(dest->str + dest->used, src->used + 1, src->str, src->used);
dest->used += src->used;
KMP_STR_BUF_INVARIANT(dest);
} // __kmp_str_buf_catbuf
diff --git a/openmp/runtime/src/z_Linux_asm.S b/openmp/runtime/src/z_Linux_asm.S
index 557f3784b3c4..8aa48d10c3af 100644
--- a/openmp/runtime/src/z_Linux_asm.S
+++ b/openmp/runtime/src/z_Linux_asm.S
@@ -1426,7 +1426,10 @@ __tid = 8
// for when we call pkfn below
push {r3-r11,lr}
// Load p_argv and &exit_frame
- ldrd r4, r5, [sp, #10*4]
+ ldr r4, [sp, #10*4]
+# if OMPT_SUPPORT
+ ldr r5, [sp, #11*4]
+# endif
# if KMP_OS_DARWIN || (defined(__thumb__) && !KMP_OS_WINDOWS)
# define FP r7