20 changes: 19 additions & 1 deletion clang/test/Driver/aix-toolchain-include.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,28 @@
// RUN: --target=powerpc-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefixes=CHECK-INTERNAL-INCLUDE,CHECK-INTERNAL-INCLUDE-CXX %s

// RUN: %clangxx -### %s 2>&1 \
// RUN: --target=powerpc64-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefixes=CHECK-INTERNAL-INCLUDE,CHECK-INTERNAL-INCLUDE-CXX %s

// RUN: %clang -### -xc %s 2>&1 \
// RUN: --target=powerpc-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-INTERNAL-INCLUDE %s

// RUN: %clang -### -xc %s 2>&1 \
// RUN: --target=powerpc64-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-INTERNAL-INCLUDE %s

// CHECK-INTERNAL-INCLUDE: "-cc1"
Expand All @@ -31,6 +35,7 @@
// CHECK-INTERNAL-INCLUDE-CXX: "-internal-isystem" "[[SYSROOT]]{{(/|\\\\)}}opt{{(/|\\\\)}}IBM{{(/|\\\\)}}openxlCSDK{{(/|\\\\)}}include{{(/|\\\\)}}c++{{(/|\\\\)}}v1"
// CHECK-INTERNAL-INCLUDE-CXX: "-D__LIBC_NO_CPP_MATH_OVERLOADS__"
// CHECK-INTERNAL-INCLUDE: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
// CHECK-INTERNAL-INCLUDE: "-internal-isystem" "[[SYSROOT]]{{(/|\\\\)}}opt{{(/|\\\\)}}IBM{{(/|\\\\)}}openxlCSDK{{(/|\\\\)}}include{{(/|\\\\)}}openmp"
// CHECK-INTERNAL-INCLUDE: "-internal-isystem" "[[SYSROOT]]/usr/include"

// Check powerpc-ibm-aix, 32-bit/64-bit. -nostdinc option.
Expand Down Expand Up @@ -73,64 +78,73 @@
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nostdlibinc \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s

// RUN: %clangxx -### %s 2>&1 \
// RUN: --target=powerpc64-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nostdlibinc \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s

// RUN: %clang -### -xc %s 2>&1 \
// RUN: --target=powerpc-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nostdlibinc \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s

// RUN: %clang -### -xc %s 2>&1 \
// RUN: --target=powerpc64-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nostdlibinc \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s

// CHECK-NOSTDLIBINC-INCLUDE: "-cc1"
// CHECK-NOSTDLIBINC-INCLUDE: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
// CHECK-NOSTDLIBINC-INCLUDE: "-isysroot" "[[SYSROOT:[^"]+]]"
// CHECK-NOSTDLIBINC-INCLUDE: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
// CHECK-NOSTDLIBINC-INCLUDE: "-internal-isystem" "[[SYSROOT]]{{(/|\\\\)}}opt{{(/|\\\\)}}IBM{{(/|\\\\)}}openxlCSDK{{(/|\\\\)}}include{{(/|\\\\)}}openmp"
// CHECK-NOSTDLIBINC-INCLUDE-NOT: "-internal-isystem" "[[SYSROOT]]{{(/|\\\\)}}opt{{(/|\\\\)}}IBM{{(/|\\\\)}}openxlCSDK{{(/|\\\\)}}include{{(/|\\\\)}}c++{{(/|\\\\)}}v1"
// CHECK-NOSTDLIBINC-INCLUDE-NOT: "-D__LIBC_NO_CPP_MATH_OVERLOADS__"
// CHECK-NOSTDLIBINC-INCLUDE-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include"
// CHECK-NOSTDLIBINC-INCLUDE-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include"

// Check powerpc-ibm-aix, 32-bit/64-bit. -nobuiltininc option.
// RUN: %clangxx -### %s 2>&1 \
// RUN: --target=powerpc-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nobuiltininc \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefixes=CHECK-NOBUILTININC-INCLUDE,CHECK-NOBUILTININC-INCLUDE-CXX %s

// RUN: %clangxx -### %s 2>&1 \
// RUN: --target=powerpc64-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nobuiltininc \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefixes=CHECK-NOBUILTININC-INCLUDE,CHECK-NOBUILTININC-INCLUDE-CXX %s

// RUN: %clang -### -xc %s 2>&1 \
// RUN: --target=powerpc-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nobuiltininc \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-NOBUILTININC-INCLUDE %s

// RUN: %clang -### -xc %s 2>&1 \
// RUN: --target=powerpc64-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nobuiltininc \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-NOBUILTININC-INCLUDE %s

// CHECK-NOBUILTININC-INCLUDE: "-cc1"
Expand All @@ -139,6 +153,7 @@
// CHECK-NOBUILTININC-INCLUDE-NOT: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
// CHECK-NOBUILTININC-INCLUDE-CXX: "-internal-isystem" "[[SYSROOT]]{{(/|\\\\)}}opt{{(/|\\\\)}}IBM{{(/|\\\\)}}openxlCSDK{{(/|\\\\)}}include{{(/|\\\\)}}c++{{(/|\\\\)}}v1"
// CHECK-NOBUILTININC-INCLUDE-CXX: "-D__LIBC_NO_CPP_MATH_OVERLOADS__"
// CHECK-NOBUILTININC-INCLUDE: "-internal-isystem" "[[SYSROOT]]{{(/|\\\\)}}opt{{(/|\\\\)}}IBM{{(/|\\\\)}}openxlCSDK{{(/|\\\\)}}include{{(/|\\\\)}}openmp"
// CHECK-NOBUILTININC-INCLUDE: "-internal-isystem" "[[SYSROOT]]/usr/include"

// Check powerpc-ibm-aix, 32-bit/64-bit. -nostdinc++ option.
Expand All @@ -147,13 +162,15 @@
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nostdinc++ \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-NOSTDINCXX-INCLUDE %s

// RUN: %clangxx -### %s 2>&1 \
// RUN: --target=powerpc64-ibm-aix \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_aix_tree \
// RUN: -nostdinc++ \
// RUN: -fopenmp \
// RUN: | FileCheck -check-prefix=CHECK-NOSTDINCXX-INCLUDE %s

// CHECK-NOSTDINCXX-INCLUDE: "-cc1"
Expand All @@ -162,6 +179,7 @@
// CHECK-NOSTDINCXX-INCLUDE: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
// CHECK-NOSTDINCXX-INCLUDE-NOT: "-internal-isystem" "[[SYSROOT]]{{(/|\\\\)}}opt{{(/|\\\\)}}IBM{{(/|\\\\)}}openxlCSDK{{(/|\\\\)}}include{{(/|\\\\)}}c++{{(/|\\\\)}}v1"
// CHECK-NOSTDINCXX-INCLUDE-NOT: "-D__LIBC_NO_CPP_MATH_OVERLOADS__"
// CHECK-NOSTDINCXX-INCLUDE: "-internal-isystem" "[[SYSROOT]]{{(/|\\\\)}}opt{{(/|\\\\)}}IBM{{(/|\\\\)}}openxlCSDK{{(/|\\\\)}}include{{(/|\\\\)}}openmp"
// CHECK-NOSTDINCXX-INCLUDE: "-internal-isystem" "[[SYSROOT]]/usr/include"

// Check powerpc-ibm-aix, 32-bit. -stdlib=libstdc++ invokes fatal error.
Expand Down
2 changes: 2 additions & 0 deletions clang/test/Driver/compress.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// XFAIL: system-aix

// REQUIRES: zlib

// RUN: %clang -### -fintegrated-as -Wa,-compress-debug-sections -c %s 2>&1 | FileCheck -check-prefix CHECK-_COMPRESS_DEBUG_SECTIONS %s
Expand Down
3 changes: 0 additions & 3 deletions clang/test/Driver/response-file-errs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// AIX reacts on opening directory differently than other systems.
// XFAIL: system-aix

// If response file does not exist, '@file; directive remains unexpanded in
// command line.
//
Expand Down
461 changes: 461 additions & 0 deletions clang/test/InstallAPI/alias_list.test

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion clang/test/InstallAPI/mismatching-objc-class-symbols.test
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
; RUN: llvm-readtapi -compare %t/mismatching.tbd %t/mismatching-expected.tbd

// Try out a dylib that only has 1 symbol for a ObjCClass, but is represented in header.
; RUN: clang-installapi -target arm64-apple-macos14 \
; RUN: clang-installapi -target arm64-apple-macos14 -dynamiclib \
; RUN: -install_name tmp.dylib --verify-against=%t/libswift-objc.dylib \
; RUN: -I%t/usr/include %t/inputs.json -o %t/matching.tbd \
; RUN: --verify-mode=Pedantic \
Expand Down
27 changes: 27 additions & 0 deletions clang/test/Modules/reduced-bmi-empty-module-purview-std.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Test that we won't write additional information from std namespace by default
// into the Reduced BMI if the module purview is empty.
//
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-reduced-module-interface -o %t/A.pcm
// RUN: llvm-bcanalyzer --dump --disable-histogram --show-binary-blobs %t/A.pcm > %t/A.dump
// RUN: cat %t/A.dump | FileCheck %t/A.cppm

//--- std.h
namespace std {
typedef decltype(sizeof(0)) size_t;
enum class align_val_t : std::size_t {};

class bad_alloc { };
}

//--- A.cppm
module;
#include "std.h"
export module A;

// CHECK-NOT: <DECL_NAMESPACE
// CHECK-NOT: <DECL_CONTEXT_LEXICAL
// CHECK-NOT: <DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD
96 changes: 96 additions & 0 deletions clang/test/Modules/reduced-bmi-empty-module-purview.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Test that we won't write additional information into the Reduced BMI if the
// module purview is empty.
//
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-reduced-module-interface -o %t/M.pcm
// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-reduced-module-interface -o %t/A.pcm \
// RUN: -fmodule-file=M=%t/M.pcm
// RUN: llvm-bcanalyzer --dump --disable-histogram --show-binary-blobs %t/A.pcm > %t/A.dump
// RUN: cat %t/A.dump | FileCheck %t/A.cppm
//
// RUN: %clang_cc1 -std=c++20 %t/A1.cppm -emit-reduced-module-interface -o %t/A1.pcm \
// RUN: -fmodule-file=M=%t/M.pcm
// RUN: llvm-bcanalyzer --dump --disable-histogram --show-binary-blobs %t/A1.pcm > %t/A1.dump
// RUN: cat %t/A1.dump | FileCheck %t/A1.cppm

//--- foo.h
namespace ns {
template <class C>
class A {

};

extern template class A<short>;

inline A<int> a() { return A<int>(); }
template <class T>
A<T> _av_ = A<T>();

auto _av_1 = _av_<int>;
auto _av_2 = _av_<double>;

template <>
class A<void> {

};

void func(A<int>, ...) {

}

}

struct S {
union {
unsigned int V;
struct {
int v1;
int v2;
ns::A<int> a1;
} WESQ;
};

union {
double d;
struct {
int v1;
unsigned v2;
ns::A<unsigned> a1;
} Another;
};
};

//--- M.cppm
module;
#include "foo.h"
export module M;
export namespace nv {
using ns::A;
using ns::a;
using ns::_av_;

using ns::func;
}
using ::S;

//--- A.cppm
module;
#include "foo.h"
export module A;
import M;

// CHECK-NOT: <DECL_CXX_RECORD
// CHECK-NOT: <DECL_UPDATE_OFFSETS

//--- A1.cppm
module;
import M;
#include "foo.h"
export module A;

// CHECK-NOT: <DECL_CXX_RECORD
// CHECK-NOT: <DECL_UPDATE_OFFSETS

22 changes: 22 additions & 0 deletions clang/test/Modules/unreached-static-entities.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Test that the static function only used in non-inline functions won't get emitted
// into the BMI.
//
// RUN: rm -rf %t
// RUN: mkdir -p %t
//
// RUN: %clang_cc1 -std=c++20 %s -emit-reduced-module-interface -o %t/S.pcm
// RUN: llvm-bcanalyzer --dump --disable-histogram --show-binary-blobs %t/S.pcm > %t/S.dump
// RUN: cat %t/S.dump | FileCheck %s

export module S;
static int static_func() {
return 43;
}

export int func() {
return static_func();
}

// CHECK: <DECL_FUNCTION
// Checks that we won't see a second function
// CHECK-NOT: <DECL_FUNCTION
2 changes: 1 addition & 1 deletion clang/test/Sema/aarch64-cpu-supports.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ int test_aarch64_features(void) {
// expected-warning@+1 {{invalid cpu feature string}}
if (__builtin_cpu_supports("default"))
return 6;
if (__builtin_cpu_supports(" ssbs + crc "))
if (__builtin_cpu_supports(" ssbs + bti "))
return 7;
return 0;
}
21 changes: 11 additions & 10 deletions clang/test/Sema/attr-target-clones-aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void __attribute__((target_clones("ssbs+ls64"))) warn2(void);

// expected-error@+2 {{'target_clones' and 'target_version' attributes are not compatible}}
// expected-note@+1 {{conflicting attribute is here}}
void __attribute__((target_version("bf16"), target_clones("sme+memtag"))) not_compat(void);
void __attribute__((target_version("sve-bf16"), target_clones("sme+memtag"))) not_compat(void);

int redecl(void);
int __attribute__((target_clones("frintts", "simd+fp", "default"))) redecl(void) { return 1; }
Expand All @@ -21,25 +21,26 @@ int __attribute__((target_clones("sve+dotprod"))) redecl3(void);
int redecl3(void);

int __attribute__((target_clones("rng", "fp16fml+fp", "default"))) redecl4(void);
// expected-error@+2 {{'target_clones' attribute does not match previous declaration}}
// expected-error@+3 {{'target_clones' attribute does not match previous declaration}}
// expected-note@-2 {{previous declaration is here}}
int __attribute__((target_clones("dpb2+memtag+rpres+ls64", "bf16+dpb+sha2", "default"))) redecl4(void) { return 1; }
// expected-warning@+1 {{version list contains entries that don't impact code generation}}
int __attribute__((target_clones("dgh+memtag+rpres+ls64_v", "ebf16+dpb+sha1", "default"))) redecl4(void) { return 1; }

int __attribute__((target_version("flagm2"))) redef2(void) { return 1; }
// expected-error@+2 {{multiversioned function redeclarations require identical target attributes}}
// expected-note@-2 {{previous declaration is here}}
int __attribute__((target_clones("flagm2", "default"))) redef2(void) { return 1; }

int __attribute__((target_clones("f32mm", "f64mm", "sha3+fp"))) redef3(void) { return 1; }
int __attribute__((target_clones("f32mm", "f64mm", "sha1+fp"))) redef3(void) { return 1; }
// expected-error@+2 {{'target_clones' attribute does not match previous declaration}}
// expected-note@-2 {{previous declaration is here}}
int __attribute__((target_clones("f32mm", "sha3+fp", "f64mm"))) redef3(void) { return 1; }
int __attribute__((target_clones("f32mm", "sha1+fp", "f64mm"))) redef3(void) { return 1; }

int __attribute__((target_clones("rdm+lse+rdm", "lse+rdm"))) dup1(void) { return 1; }
// expected-warning@+1 {{version list contains duplicate entries}}
int __attribute__((target_clones("rdm+lse+rdm", "rdm+lse+rdm"))) dup2(void) { return 2; }
// expected-warning@+1 {{version list contains duplicate entries}}
int __attribute__((target_clones("rcpc2+sve2-aes", "rcpc2+sve2-aes"))) dup3(void) { return 3; }
int __attribute__((target_clones("rcpc2+sve2-pmull128", "rcpc2+sve2-pmull128"))) dup3(void) { return 3; }
// expected-warning@+1 {{version list contains duplicate entries}}
void __attribute__((target_clones("sha3", "default", "default"))) dup4(void);
// expected-warning@+2 {{version list contains duplicate entries}}
Expand All @@ -48,7 +49,7 @@ int __attribute__((target_clones("fp", "fp", "crc+dotprod", "dotprod+crc"))) dup

// expected-warning@+1 {{version list contains duplicate entries}}
int __attribute__((target_clones("fp16+memtag", "memtag+fp16"))) dup6(void) { return 6; }
int __attribute__((target_clones("simd+ssbs", "simd+dpb2"))) dup7(void) { return 7; }
int __attribute__((target_clones("simd+ssbs2", "simd+dpb2"))) dup7(void) { return 7; }

// expected-warning@+1 {{unsupported '' in the 'target_clones' attribute string;}}
void __attribute__((target_clones(""))) empty_target_1(void);
Expand All @@ -71,13 +72,13 @@ empty_target_5(void);
void __attribute__((target_clones("sve2-bitperm", "sve2-bitperm")))
dupe_normal(void);

void __attribute__((target_clones("default"), target_clones("memtag+mops"))) dupe_normal2(void);
void __attribute__((target_clones("default"), target_clones("memtag3+bti"))) dupe_normal2(void);

int mv_after_use(void);
int useage(void) {
return mv_after_use();
}
// expected-error@+1 {{function declaration cannot become a multiversioned function after first usage}}
int __attribute__((target_clones("sve2-sha3+ssbs", "sm4"))) mv_after_use(void) { return 1; }
int __attribute__((target_clones("sve2-sha3+ssbs2", "sm4"))) mv_after_use(void) { return 1; }
// expected-error@+1 {{'main' cannot be a multiversioned function}}
int __attribute__((target_clones("sve2-aes"))) main() { return 1; }
int __attribute__((target_clones("sve-i8mm"))) main() { return 1; }
18 changes: 9 additions & 9 deletions clang/test/Sema/attr-target-version.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ int __attribute__((target_version("aes"))) foo(void) { return 1; }
int __attribute__((target_version("default"))) foo(void) { return 2; }

//expected-note@+1 {{previous definition is here}}
int __attribute__((target_version("sha3 + aes "))) foo(void) { return 1; }
int __attribute__((target_version("sha3 + pmull "))) foo(void) { return 1; }
//expected-note@-1 {{previous definition is here}}

//expected-error@+1 {{redefinition of 'foo'}}
Expand All @@ -32,19 +32,19 @@ __attribute__ ((target("bf16,sve,sve2,dotprod"))) int func(void) { return 1; }
__attribute__ ((target("default"))) int func(void) { return 0; }

//expected-note@+1 {{previous declaration is here}}
void __attribute__((target_version("mops+flagm2"))) one(void) {}
void __attribute__((target_version("bti+flagm2"))) one(void) {}
//expected-error@+1 {{multiversioned function redeclarations require identical target attributes}}
void __attribute__((target_version("flagm2+mops"))) one(void) {}
void __attribute__((target_version("flagm2+bti"))) one(void) {}

void __attribute__((target_version("ssbs+sha2"))) two(void) {}
void __attribute__((target_version("ssbs+sha1"))) two(void) {}
void __attribute__((target_version("ssbs+fp16fml"))) two(void) {}

//expected-error@+1 {{'main' cannot be a multiversioned function}}
int __attribute__((target_version("lse"))) main(void) { return 1; }

// It is ok for the default version to appear first.
int default_first(void) { return 1; }
int __attribute__((target_version("crc"))) default_first(void) { return 2; }
int __attribute__((target_version("dit"))) default_first(void) { return 2; }
int __attribute__((target_version("mops"))) default_first(void) { return 3; }

// It is ok if the default version is between other versions.
Expand Down Expand Up @@ -77,7 +77,7 @@ void __attribute__((target_version("rdm+rng+crc"))) redef(void) {}
void __attribute__((target_version("rdm+rng+crc"))) redef(void) {}

int def(void);
void __attribute__((target_version("crc"))) nodef(void);
void __attribute__((target_version("dit"))) nodef(void);
void __attribute__((target_version("ls64"))) nodef(void);
void __attribute__((target_version("aes"))) ovl(void);
void __attribute__((target_version("default"))) ovl(void);
Expand All @@ -89,20 +89,20 @@ int bar() {
return def();
}
// expected-error@+1 {{function declaration cannot become a multiversioned function after first usage}}
int __attribute__((target_version("sha3"))) def(void) { return 1; }
int __attribute__((target_version("sha1"))) def(void) { return 1; }

int __attribute__((target_version("sve"))) prot();
// expected-error@-1 {{multiversioned function must have a prototype}}

int __attribute__((target_version("aes"))) rtype(int);
int __attribute__((target_version("pmull"))) rtype(int);
// expected-error@+1 {{multiversioned function declaration has a different return type}}
float __attribute__((target_version("rdm"))) rtype(int);

int __attribute__((target_version("sha2"))) combine(void) { return 1; }
// expected-error@+1 {{multiversioned function declaration has a different calling convention}}
int __attribute__((aarch64_vector_pcs, target_version("sha3"))) combine(void) { return 2; }

int __attribute__((target_version("fp+aes+sha3+rcpc"))) unspec_args() { return -1; }
int __attribute__((target_version("fp+aes+pmull+rcpc"))) unspec_args() { return -1; }
// expected-error@-1 {{multiversioned function must have a prototype}}
// expected-error@+1 {{multiversioned function must have a prototype}}
int __attribute__((target_version("default"))) unspec_args() { return 0; }
Expand Down
6 changes: 6 additions & 0 deletions clang/test/SemaCXX/PR75221.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// RUN: %clang_cc1 -verify -std=c++11 -fsyntax-only %s

template <class T> using foo = struct foo { // expected-error {{'foo' cannot be defined in a type alias template}}
T size = 0;
};
foo a;
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s

// Test that the exclude_from_explicit_instantiation attribute is ignored
// for local classes and members thereof.

#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) // expected-note 0+{{expanded from macro}}

namespace N0 {

template<typename T>
void f() {
struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION A { // expected-warning {{attribute ignored on local class}}
// expected-note@-1 2{{in instantiation of}}
EXCLUDE_FROM_EXPLICIT_INSTANTIATION void g(T t) { // expected-warning {{attribute ignored on local class member}}
*t; // expected-error {{indirection requires pointer operand ('int' invalid)}}
}

struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION B { // expected-warning {{attribute ignored on local class}}
void h(T t) {
*t; // expected-error {{indirection requires pointer operand ('int' invalid)}}
}
};
};
}

template void f<int>(); // expected-note 2{{in instantiation of}}

}

// This is a reduced example from libc++ which required that 'value'
// be prefixed with 'this->' because the definition of 'Local::operator A'
// was not instantiated when the definition of 'g' was.
namespace N1 {

struct A { };

struct B {
operator A() {
return A();
}
};

template<typename T>
auto f(T t) {
return A(t);
}

template<typename T>
auto g(T t) {
struct Local {
T value;

EXCLUDE_FROM_EXPLICIT_INSTANTIATION // expected-warning {{attribute ignored on local class member}}
operator A() {
return A(value);
}
};

return f(Local(t));
}

auto x = g(B());

}
16 changes: 8 additions & 8 deletions clang/test/SemaCXX/attr-target-version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ int __attribute__((target_version("dpb"))) diff_link(void);

int __attribute__((target_version("memtag"))) diff_link1(void) { return 1; }
//expected-error@+1 {{multiversioned function declaration has a different linkage}}
static int __attribute__((target_version("mops"))) diff_link1(void);
static int __attribute__((target_version("bti"))) diff_link1(void);

int __attribute__((target_version("flagm2"))) diff_link2(void) { return 1; }
extern int __attribute__((target_version("flagm"))) diff_link2(void);

namespace {
static int __attribute__((target_version("memtag"))) diff_link2(void) { return 2; }
static int __attribute__((target_version("memtag3"))) diff_link2(void) { return 2; }
int __attribute__((target_version("sve2-bitperm"))) diff_link2(void) { return 1; }
} // namespace

Expand All @@ -49,7 +49,7 @@ double __attribute__((target_version("rcpc"))) diff_type1(void);

auto __attribute__((target_version("rcpc2"))) diff_type2(void) -> int { return 1; }
//expected-error@+1 {{multiversioned function declaration has a different return type}}
auto __attribute__((target_version("sve2-aes"))) diff_type2(void) -> long { return (long)1; }
auto __attribute__((target_version("sve-bf16"))) diff_type2(void) -> long { return (long)1; }

int __attribute__((target_version("fp16fml"))) diff_type3(void) noexcept(false) { return 1; }
//expected-error@+2 {{exception specification in declaration does not match previous declaration}}
Expand All @@ -75,7 +75,7 @@ auto __attribute__((target_version("dpb2"))) ret3(void) -> int { return 1; }
class Cls {
__attribute__((target_version("rng"))) Cls();
// expected-error@-1 {{attribute 'target_version' multiversioned functions do not yet support constructors}}
__attribute__((target_version("sve2-aes"))) ~Cls();
__attribute__((target_version("sve-i8mm"))) ~Cls();
// expected-error@-1 {{attribute 'target_version' multiversioned functions do not yet support destructors}}

Cls &__attribute__((target_version("f32mm"))) operator=(const Cls &) = default;
Expand All @@ -98,11 +98,11 @@ __attribute__((target_version("jscvt"))) void Decl();
} // namespace Nms

class Out {
int __attribute__((target_version("mops"))) func(void);
int __attribute__((target_version("ssbs"))) func(void);
int __attribute__((target_version("bti"))) func(void);
int __attribute__((target_version("ssbs2"))) func(void);
};
int __attribute__((target_version("mops"))) Out::func(void) { return 1; }
int __attribute__((target_version("ssbs"))) Out::func(void) { return 2; }
int __attribute__((target_version("bti"))) Out::func(void) { return 1; }
int __attribute__((target_version("ssbs2"))) Out::func(void) { return 2; }
// expected-error@+3 {{out-of-line definition of 'func' does not match any declaration in 'Out'}}
// expected-note@-3 {{member declaration nearly matches}}
// expected-note@-3 {{member declaration nearly matches}}
Expand Down
5 changes: 5 additions & 0 deletions clang/test/SemaCXX/cxx11-attr-print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,8 @@ template struct S<int>;

// CHECK: using Small2 {{\[}}[gnu::mode(byte)]] = int;
using Small2 [[gnu::mode(byte)]] = int;

class FinalNonTemplate final {};
// CHECK: class FinalNonTemplate final {
template <typename T> class FinalTemplate final {};
// CHECK: template <typename T> class FinalTemplate final {
10 changes: 10 additions & 0 deletions clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,13 @@ Bar t = Foo<K<Container>>();

Bar s = 1; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of}}
} // namespace test20

namespace test21 {
template <typename T, unsigned N>
struct Array { const T member[N]; };
template <unsigned N>
using String = Array<char, N>;

// Verify no crash on constructing the aggregate deduction guides.
String s("hello");
} // namespace test21
4 changes: 2 additions & 2 deletions clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ typedef vector<float, 3> float3;
RWBuffer<float3> Buffer;

// expected-error@+2 {{class template 'RWBuffer' requires template arguments}}
// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer final}}
// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer}}
RWBuffer BufferErr1;

// expected-error@+2 {{too few template arguments for class template 'RWBuffer'}}
// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer final}}
// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer}}
RWBuffer<> BufferErr2;

[numthreads(1,1,1)]
Expand Down
4 changes: 4 additions & 0 deletions clang/test/SemaObjCXX/Inputs/nullability-consistency-smart.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ void f1(int * _Nonnull);
void f2(Smart); // OK, not required on smart-pointer types
using Alias = Smart;
void f3(Alias);

template <class T> class _Nullable SmartTmpl;
void f2(SmartTmpl<int>);
template <class T> void f2(SmartTmpl<T>);
2 changes: 1 addition & 1 deletion clang/tools/clang-installapi/ClangInstallAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ static bool run(ArrayRef<const char *> Args, const char *ProgName) {
return EXIT_FAILURE;

// Assign attributes for serialization.
InterfaceFile IF(Ctx.Verifier->getExports());
InterfaceFile IF(Ctx.Verifier->takeExports());
// Assign attributes that are the same per slice first.
for (const auto &TargetInfo : Opts.DriverOpts.Targets) {
IF.addTarget(TargetInfo.first);
Expand Down
24 changes: 23 additions & 1 deletion clang/tools/clang-installapi/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,11 @@ bool Options::processLinkerOptions(InputArgList &Args) {

LinkerOpts.IsDylib = Args.hasArg(drv::OPT_dynamiclib);

for (auto *Arg : Args.filtered(drv::OPT_alias_list)) {
LinkerOpts.AliasLists.emplace_back(Arg->getValue());
Arg->claim();
}

LinkerOpts.AppExtensionSafe = Args.hasFlag(
drv::OPT_fapplication_extension, drv::OPT_fno_application_extension,
/*Default=*/LinkerOpts.AppExtensionSafe);
Expand Down Expand Up @@ -684,6 +689,23 @@ InstallAPIContext Options::createContext() {
return Ctx;
Ctx.Reexports = Reexports;

// Collect symbols from alias lists.
AliasMap Aliases;
for (const StringRef ListPath : LinkerOpts.AliasLists) {
auto Buffer = FM->getBufferForFile(ListPath);
if (auto Err = Buffer.getError()) {
Diags->Report(diag::err_cannot_open_file) << ListPath << Err.message();
return Ctx;
}
Expected<AliasMap> Result = parseAliasList(Buffer.get());
if (!Result) {
Diags->Report(diag::err_cannot_read_alias_list)
<< ListPath << toString(Result.takeError());
return Ctx;
}
Aliases.insert(Result.get().begin(), Result.get().end());
}

// Attempt to find umbrella headers by capturing framework name.
StringRef FrameworkName;
if (!LinkerOpts.IsDylib)
Expand Down Expand Up @@ -849,7 +871,7 @@ InstallAPIContext Options::createContext() {
}

Ctx.Verifier = std::make_unique<DylibVerifier>(
std::move(*Slices), std::move(ReexportedIFs), Diags,
std::move(*Slices), std::move(ReexportedIFs), std::move(Aliases), Diags,
DriverOpts.VerifyMode, DriverOpts.Zippered, DriverOpts.Demangle,
DriverOpts.DSYMPath);
return Ctx;
Expand Down
3 changes: 3 additions & 0 deletions clang/tools/clang-installapi/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ struct LinkerOptions {
/// \brief Additional library search paths.
PathSeq LibPaths;

/// \brief List of alias symbol files.
PathSeq AliasLists;

/// \brief The install name to use for the dynamic library.
std::string InstallName;

Expand Down
37 changes: 28 additions & 9 deletions clang/unittests/AST/DeclPrinterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,13 @@ ::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code,
ExpectedPrinted, "input.cc");
}

::testing::AssertionResult PrintedDeclCXX11Matches(
StringRef Code,
const DeclarationMatcher &NodeMatch,
StringRef ExpectedPrinted) {
::testing::AssertionResult
PrintedDeclCXX11Matches(StringRef Code, const DeclarationMatcher &NodeMatch,
StringRef ExpectedPrinted,
PrintingPolicyAdjuster PolicyModifier = nullptr) {
std::vector<std::string> Args(1, "-std=c++11");
return PrintedDeclMatches(Code,
Args,
NodeMatch,
ExpectedPrinted,
"input.cc");
return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.cc",
PolicyModifier);
}

::testing::AssertionResult PrintedDeclCXX11nonMSCMatches(
Expand Down Expand Up @@ -1555,3 +1552,25 @@ TEST(DeclPrinter, VarDeclWithInitializer) {
PrintedDeclCXX17Matches("void foo() {int arr[42]; for(int a : arr);}",
namedDecl(hasName("a")).bind("id"), "int a"));
}

TEST(DeclPrinter, TestTemplateFinal) {
// By default we should print 'final' keyword whether class is implicitly or
// explicitly marked final.
ASSERT_TRUE(PrintedDeclCXX11Matches(
"template<typename T>\n"
"class FinalTemplate final {};",
classTemplateDecl(hasName("FinalTemplate")).bind("id"),
"template <typename T> class FinalTemplate final {}"));
}

TEST(DeclPrinter, TestTemplateFinalWithPolishForDecl) {
// clangd relies on the 'final' keyword being printed when
// PolishForDeclaration is enabled, so make sure it is even if implicit attrs
// are disabled.
ASSERT_TRUE(PrintedDeclCXX11Matches(
"template<typename T>\n"
"class FinalTemplate final {};",
classTemplateDecl(hasName("FinalTemplate")).bind("id"),
"template <typename T> class FinalTemplate final {}",
[](PrintingPolicy &Policy) { Policy.PolishForDeclaration = true; }));
}
7 changes: 1 addition & 6 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27339,12 +27339,6 @@ TEST_F(FormatTest, PPDirectivesAndCommentsInBracedInit) {
getLLVMStyleWithColumns(30));
}

TEST_F(FormatTest, StreamOutputOperator) {
verifyFormat("std::cout << \"foo\" << \"bar\" << baz;");
verifyFormat("std::cout << \"foo\\n\"\n"
" << \"bar\";");
}

TEST_F(FormatTest, BreakAdjacentStringLiterals) {
constexpr StringRef Code{
"return \"Code\" \"\\0\\52\\26\\55\\55\\0\" \"x013\" \"\\02\\xBA\";"};
Expand All @@ -27359,6 +27353,7 @@ TEST_F(FormatTest, BreakAdjacentStringLiterals) {
Style.BreakAdjacentStringLiterals = false;
verifyFormat(Code, Style);
}

} // namespace
} // namespace test
} // namespace format
Expand Down
19 changes: 10 additions & 9 deletions clang/unittests/Format/TokenAnnotatorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,16 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_OverloadedOperatorLParen);
EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_FunctionLBrace);
EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);

Tokens = annotate("if (new && num) {\n"
" new = 1;\n"
"}\n"
"if (!delete && num) {\n"
" delete = 1;\n"
"}");
ASSERT_EQ(Tokens.size(), 26u) << Tokens;
EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_BinaryOperator);
EXPECT_TOKEN(Tokens[16], tok::ampamp, TT_BinaryOperator);
}

TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
Expand Down Expand Up @@ -2841,15 +2851,6 @@ TEST_F(TokenAnnotatorTest, BraceKind) {
EXPECT_BRACE_KIND(Tokens[16], BK_BracedInit);
}

TEST_F(TokenAnnotatorTest, StreamOperator) {
auto Tokens = annotate("\"foo\\n\" << aux << \"foo\\n\" << \"foo\";");
ASSERT_EQ(Tokens.size(), 9u) << Tokens;
EXPECT_FALSE(Tokens[1]->MustBreakBefore);
EXPECT_FALSE(Tokens[3]->MustBreakBefore);
// Only break between string literals if the former ends with \n.
EXPECT_TRUE(Tokens[5]->MustBreakBefore);
}

TEST_F(TokenAnnotatorTest, UnderstandsElaboratedTypeSpecifier) {
auto Tokens = annotate("auto foo() -> enum En {}");
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
Expand Down
2 changes: 1 addition & 1 deletion clang/utils/TableGen/ClangAttrEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1608,7 +1608,7 @@ writePrettyPrintFunction(const Record &R,
Prefix = "[";
Suffix = "]";
} else if (Variety == "Keyword") {
Prefix = " ";
Prefix = "";
Suffix = "";
} else if (Variety == "Pragma") {
Prefix = "#pragma ";
Expand Down
6 changes: 0 additions & 6 deletions compiler-rt/cmake/Modules/CompilerRTUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -368,12 +368,6 @@ macro(construct_compiler_rt_default_triple)
"Default triple for which compiler-rt runtimes will be built.")
endif()

if ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
execute_process(COMMAND ${CMAKE_C_COMPILER} --target=${COMPILER_RT_DEFAULT_TARGET_TRIPLE} -print-effective-triple
OUTPUT_VARIABLE COMPILER_RT_DEFAULT_TARGET_TRIPLE
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()

string(REPLACE "-" ";" LLVM_TARGET_TRIPLE_LIST ${COMPILER_RT_DEFAULT_TARGET_TRIPLE})
list(GET LLVM_TARGET_TRIPLE_LIST 0 COMPILER_RT_DEFAULT_TARGET_ARCH)

Expand Down
17 changes: 16 additions & 1 deletion compiler-rt/lib/builtins/cpu_model/aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,42 +67,57 @@ enum CPUFeatures {
FEAT_FP,
FEAT_SIMD,
FEAT_CRC,
FEAT_SHA1,
FEAT_SHA2,
FEAT_SHA3,
FEAT_AES,
FEAT_PMULL,
FEAT_FP16,
FEAT_DIT,
FEAT_DPB,
FEAT_DPB2,
FEAT_JSCVT,
FEAT_FCMA,
FEAT_RCPC,
FEAT_RCPC2,
FEAT_FRINTTS,
FEAT_DGH,
FEAT_I8MM,
FEAT_BF16,
FEAT_EBF16,
FEAT_RPRES,
FEAT_SVE,
FEAT_SVE_BF16,
FEAT_SVE_EBF16,
FEAT_SVE_I8MM,
FEAT_SVE_F32MM,
FEAT_SVE_F64MM,
FEAT_SVE2,
FEAT_SVE_AES,
FEAT_SVE_PMULL128,
FEAT_SVE_BITPERM,
FEAT_SVE_SHA3,
FEAT_SVE_SM4,
FEAT_SME,
FEAT_MEMTAG,
FEAT_MEMTAG2,
FEAT_MEMTAG3,
FEAT_SB,
FEAT_PREDRES,
FEAT_SSBS,
FEAT_SSBS2,
FEAT_BTI,
FEAT_LS64,
FEAT_LS64_V,
FEAT_LS64_ACCDATA,
FEAT_WFXT,
FEAT_SME_F64,
FEAT_SME_I64,
FEAT_SME2,
FEAT_RCPC3,
FEAT_MOPS,
FEAT_MAX,
FEAT_EXT = 47, // Reserved to indicate presence of additional features field
FEAT_EXT = 62, // Reserved to indicate presence of additional features field
// in __aarch64_cpu_features
FEAT_INIT // Used as flag of features initialization completion
};
Expand Down
6 changes: 5 additions & 1 deletion compiler-rt/lib/builtins/cpu_model/aarch64/fmv/apple.inc
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ void __init_cpu_features_resolver(void) {
{"hw.optional.floatingpoint", FEAT_FP},
{"hw.optional.AdvSIMD", FEAT_SIMD},
{"hw.optional.armv8_crc32", FEAT_CRC},
{"hw.optional.arm.FEAT_SHA1", FEAT_SHA1},
{"hw.optional.arm.FEAT_SHA256", FEAT_SHA2},
{"hw.optional.arm.FEAT_SHA3", FEAT_SHA3},
{"hw.optional.arm.FEAT_AES", FEAT_AES},
{"hw.optional.arm.FEAT_PMULL", FEAT_PMULL},
{"hw.optional.arm.FEAT_FP16", FEAT_FP16},
{"hw.optional.arm.FEAT_DIT", FEAT_DIT},
{"hw.optional.arm.FEAT_DPB", FEAT_DPB},
{"hw.optional.arm.FEAT_DPB2", FEAT_DPB2},
{"hw.optional.arm.FEAT_JSCVT", FEAT_JSCVT},
Expand All @@ -50,7 +53,8 @@ void __init_cpu_features_resolver(void) {
{"hw.optional.arm.FEAT_BF16", FEAT_BF16},
{"hw.optional.arm.FEAT_SB", FEAT_SB},
{"hw.optional.arm.FEAT_SPECRES", FEAT_PREDRES},
{"hw.optional.arm.FEAT_SSBS", FEAT_SSBS},
{"hw.optional.arm.FEAT_SSBS", FEAT_SSBS2},
{"hw.optional.arm.FEAT_BTI", FEAT_BTI},
};

for (size_t I = 0, E = sizeof(feature_checks) / sizeof(feature_checks[0]);
Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/fuchsia.inc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ void __init_cpu_features_resolver() {
setCPUFeature(FEAT_SIMD);
if (features & ZX_ARM64_FEATURE_ISA_AES)
setCPUFeature(FEAT_AES);
if (features & ZX_ARM64_FEATURE_ISA_PMULL)
setCPUFeature(FEAT_PMULL);
if (features & ZX_ARM64_FEATURE_ISA_SHA1)
setCPUFeature(FEAT_SHA1);
if (features & ZX_ARM64_FEATURE_ISA_SHA256)
setCPUFeature(FEAT_SHA2);
if (features & ZX_ARM64_FEATURE_ISA_CRC32)
Expand Down
42 changes: 40 additions & 2 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/mrs.inc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
hwcap2 = arg->_hwcap2;
if (hwcap & HWCAP_CRC32)
setCPUFeature(FEAT_CRC);
if (hwcap & HWCAP_PMULL)
setCPUFeature(FEAT_PMULL);
if (hwcap & HWCAP_FLAGM)
setCPUFeature(FEAT_FLAGM);
if (hwcap2 & HWCAP2_FLAGM2) {
Expand All @@ -32,12 +34,16 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
setCPUFeature(FEAT_FP16);
setCPUFeature(FEAT_FP);
}
if (hwcap & HWCAP_DIT)
setCPUFeature(FEAT_DIT);
if (hwcap & HWCAP_ASIMDRDM)
setCPUFeature(FEAT_RDM);
if (hwcap & HWCAP_ILRCPC)
setCPUFeature(FEAT_RCPC2);
if (hwcap & HWCAP_AES)
setCPUFeature(FEAT_AES);
if (hwcap & HWCAP_SHA1)
setCPUFeature(FEAT_SHA1);
if (hwcap & HWCAP_SHA2)
setCPUFeature(FEAT_SHA2);
if (hwcap & HWCAP_JSCVT)
Expand All @@ -47,11 +53,22 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
if (hwcap & HWCAP_SB)
setCPUFeature(FEAT_SB);
if (hwcap & HWCAP_SSBS)
setCPUFeature(FEAT_SSBS);
if (hwcap2 & HWCAP2_MTE)
setCPUFeature(FEAT_SSBS2);
if (hwcap2 & HWCAP2_MTE) {
setCPUFeature(FEAT_MEMTAG);
setCPUFeature(FEAT_MEMTAG2);
}
if (hwcap2 & HWCAP2_MTE3) {
setCPUFeature(FEAT_MEMTAG);
setCPUFeature(FEAT_MEMTAG2);
setCPUFeature(FEAT_MEMTAG3);
}
if (hwcap2 & HWCAP2_SVEAES)
setCPUFeature(FEAT_SVE_AES);
if (hwcap2 & HWCAP2_SVEPMULL) {
setCPUFeature(FEAT_SVE_AES);
setCPUFeature(FEAT_SVE_PMULL128);
}
if (hwcap2 & HWCAP2_SVEBITPERM)
setCPUFeature(FEAT_SVE_BITPERM);
if (hwcap2 & HWCAP2_SVESHA3)
Expand All @@ -66,12 +83,22 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
setCPUFeature(FEAT_RNG);
if (hwcap2 & HWCAP2_I8MM)
setCPUFeature(FEAT_I8MM);
if (hwcap2 & HWCAP2_EBF16)
setCPUFeature(FEAT_EBF16);
if (hwcap2 & HWCAP2_SVE_EBF16)
setCPUFeature(FEAT_SVE_EBF16);
if (hwcap2 & HWCAP2_DGH)
setCPUFeature(FEAT_DGH);
if (hwcap2 & HWCAP2_FRINT)
setCPUFeature(FEAT_FRINTTS);
if (hwcap2 & HWCAP2_SVEI8MM)
setCPUFeature(FEAT_SVE_I8MM);
if (hwcap2 & HWCAP2_SVEF32MM)
setCPUFeature(FEAT_SVE_F32MM);
if (hwcap2 & HWCAP2_SVEF64MM)
setCPUFeature(FEAT_SVE_F64MM);
if (hwcap2 & HWCAP2_BTI)
setCPUFeature(FEAT_BTI);
if (hwcap2 & HWCAP2_RPRES)
setCPUFeature(FEAT_RPRES);
if (hwcap2 & HWCAP2_WFXT)
Expand Down Expand Up @@ -114,6 +141,9 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
// ID_AA64ZFR0_EL1.SVEver == 0b0001
if (extractBits(ftr, 0, 4) == 0x1)
setCPUFeature(FEAT_SVE2);
// ID_AA64ZFR0_EL1.BF16 != 0b0000
if (extractBits(ftr, 20, 4) != 0x0)
setCPUFeature(FEAT_SVE_BF16);
}
getCPUFeature(ID_AA64ISAR0_EL1, ftr);
// ID_AA64ISAR0_EL1.SHA3 != 0b0000
Expand All @@ -138,6 +168,12 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
// ID_AA64ISAR1_EL1.LS64 >= 0b0001
if (extractBits(ftr, 60, 4) >= 0x1)
setCPUFeature(FEAT_LS64);
// ID_AA64ISAR1_EL1.LS64 >= 0b0010
if (extractBits(ftr, 60, 4) >= 0x2)
setCPUFeature(FEAT_LS64_V);
// ID_AA64ISAR1_EL1.LS64 >= 0b0011
if (extractBits(ftr, 60, 4) >= 0x3)
setCPUFeature(FEAT_LS64_ACCDATA);
} else {
// Set some features in case of no CPUID support
if (hwcap & (HWCAP_FP | HWCAP_FPHP)) {
Expand All @@ -151,6 +187,8 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
setCPUFeature(FEAT_RCPC);
if (hwcap2 & HWCAP2_BF16 || hwcap2 & HWCAP2_EBF16)
setCPUFeature(FEAT_BF16);
if (hwcap2 & HWCAP2_SVEBF16)
setCPUFeature(FEAT_SVE_BF16);
if (hwcap2 & HWCAP2_SVE2 && hwcap & HWCAP_SVE)
setCPUFeature(FEAT_SVE2);
if (hwcap & HWCAP_SHA3)
Expand Down
18 changes: 8 additions & 10 deletions flang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,12 @@ if (FLANG_STANDALONE_BUILD)
mark_as_advanced(LLVM_ENABLE_ASSERTIONS)
endif()

# We need a pre-built/installed version of LLVM.
find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}")
# If the user specifies a relative path to LLVM_DIR, the calls to include
# LLVM modules fail. Append the absolute path to LLVM_DIR instead.
get_filename_component(LLVM_DIR_ABSOLUTE ${LLVM_DIR}
REALPATH BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
get_filename_component(LLVM_DIR_ABSOLUTE ${LLVM_DIR} REALPATH)
list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR_ABSOLUTE})
# We need a pre-built/installed version of LLVM.
find_package(LLVM REQUIRED HINTS "${LLVM_DIR_ABSOLUTE}")

# Users might specify a path to CLANG_DIR that's:
# * a full path, or
Expand All @@ -98,7 +97,7 @@ if (FLANG_STANDALONE_BUILD)
CLANG_DIR_ABSOLUTE
${CLANG_DIR}
REALPATH
BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
${CMAKE_CURRENT_SOURCE_DIR})
list(APPEND CMAKE_MODULE_PATH ${CLANG_DIR_ABSOLUTE})

# TODO: Remove when libclangDriver is lifted out of Clang
Expand All @@ -125,14 +124,13 @@ if (FLANG_STANDALONE_BUILD)
include(AddClang)

include(TableGen)
find_package(MLIR REQUIRED CONFIG)
# Use SYSTEM for the same reasons as for LLVM includes
include_directories(SYSTEM ${MLIR_INCLUDE_DIRS})
# If the user specifies a relative path to MLIR_DIR, the calls to include
# MLIR modules fail. Append the absolute path to MLIR_DIR instead.
get_filename_component(MLIR_DIR_ABSOLUTE ${MLIR_DIR}
REALPATH BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
get_filename_component(MLIR_DIR_ABSOLUTE ${MLIR_DIR} REALPATH)
list(APPEND CMAKE_MODULE_PATH ${MLIR_DIR_ABSOLUTE})
find_package(MLIR REQUIRED CONFIG HINTS ${MLIR_DIR_ABSOLUTE})
# Use SYSTEM for the same reasons as for LLVM includes
include_directories(SYSTEM ${MLIR_INCLUDE_DIRS})
include(AddMLIR)
find_program(MLIR_TABLEGEN_EXE "mlir-tblgen" ${LLVM_TOOLS_BINARY_DIR}
NO_DEFAULT_PATH)
Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Optimizer/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def MemRefDataFlowOpt : Pass<"fir-memref-dataflow-opt", "::mlir::func::FuncOp">
def AddDebugInfo : Pass<"add-debug-info", "mlir::ModuleOp"> {
let summary = "Add the debug info";
let description = [{
Add the foundation for emitting debug info that can be understood by llvm.
Emit debug info that can be understood by llvm.
}];
let constructor = "::fir::createAddDebugInfoPass()";
let dependentDialects = [
Expand Down
6 changes: 3 additions & 3 deletions flang/include/flang/Tools/CLOptions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static llvm::cl::opt<bool> useOldAliasTags("use-old-alias-tags",
#if !defined(FLANG_EXCLUDE_CODEGEN)
DisableOption(CodeGenRewrite, "codegen-rewrite", "rewrite FIR for codegen");
DisableOption(TargetRewrite, "target-rewrite", "rewrite FIR for target");
DisableOption(DebugFoundation, "debug-foundation", "Add debug foundation");
DisableOption(DebugInfo, "debug-info", "Add debug info");
DisableOption(FirToLlvmIr, "fir-to-llvmir", "FIR to LLVM-IR dialect");
DisableOption(LlvmIrToLlvm, "llvm", "conversion to LLVM");
DisableOption(BoxedProcedureRewrite, "boxed-procedure-rewrite",
Expand Down Expand Up @@ -156,8 +156,8 @@ inline void addTargetRewritePass(mlir::PassManager &pm) {
}

inline void addDebugInfoPass(mlir::PassManager &pm) {
addPassConditionally(pm, disableDebugFoundation,
[&]() { return fir::createAddDebugInfoPass(); });
addPassConditionally(
pm, disableDebugInfo, [&]() { return fir::createAddDebugInfoPass(); });
}

inline void addFIRToLLVMPass(
Expand Down
5 changes: 2 additions & 3 deletions flang/lib/Lower/OpenMP/ClauseProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@ class ClauseProcessor {
public:
ClauseProcessor(Fortran::lower::AbstractConverter &converter,
Fortran::semantics::SemanticsContext &semaCtx,
const Fortran::parser::OmpClauseList &clauses)
: converter(converter), semaCtx(semaCtx),
clauses(makeClauses(clauses, semaCtx)) {}
const List<Clause> &clauses)
: converter(converter), semaCtx(semaCtx), clauses(clauses) {}

// 'Unique' clauses: They can appear at most once in the clause list.
bool processCollapse(
Expand Down
5 changes: 2 additions & 3 deletions flang/lib/Lower/OpenMP/DataSharingProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,12 @@ class DataSharingProcessor {
public:
DataSharingProcessor(Fortran::lower::AbstractConverter &converter,
Fortran::semantics::SemanticsContext &semaCtx,
const Fortran::parser::OmpClauseList &opClauseList,
const List<Clause> &clauses,
Fortran::lower::pft::Evaluation &eval,
bool useDelayedPrivatization = false,
Fortran::lower::SymMap *symTable = nullptr)
: hasLastPrivateOp(false), converter(converter),
firOpBuilder(converter.getFirOpBuilder()),
clauses(omp::makeClauses(opClauseList, semaCtx)), eval(eval),
firOpBuilder(converter.getFirOpBuilder()), clauses(clauses), eval(eval),
useDelayedPrivatization(useDelayedPrivatization), symTable(symTable) {}

// Privatisation is split into two steps.
Expand Down
451 changes: 213 additions & 238 deletions flang/lib/Lower/OpenMP/OpenMP.cpp

Large diffs are not rendered by default.

30 changes: 11 additions & 19 deletions flang/lib/Lower/OpenMP/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ namespace Fortran {
namespace lower {
namespace omp {

int64_t getCollapseValue(const List<Clause> &clauses) {
auto iter = llvm::find_if(clauses, [](const Clause &clause) {
return clause.id == llvm::omp::Clause::OMPC_collapse;
});
if (iter != clauses.end()) {
const auto &collapse = std::get<clause::Collapse>(iter->u);
return evaluate::ToInt64(collapse.v).value();
}
return 1;
}

void genObjectList(const ObjectList &objects,
Fortran::lower::AbstractConverter &converter,
llvm::SmallVectorImpl<mlir::Value> &operands) {
Expand All @@ -52,25 +63,6 @@ void genObjectList(const ObjectList &objects,
}
}

void genObjectList2(const Fortran::parser::OmpObjectList &objectList,
Fortran::lower::AbstractConverter &converter,
llvm::SmallVectorImpl<mlir::Value> &operands) {
auto addOperands = [&](Fortran::lower::SymbolRef sym) {
const mlir::Value variable = converter.getSymbolAddress(sym);
if (variable) {
operands.push_back(variable);
} else if (const auto *details =
sym->detailsIf<Fortran::semantics::HostAssocDetails>()) {
operands.push_back(converter.getSymbolAddress(details->symbol()));
converter.copySymbolBinding(details->symbol(), sym);
}
};
for (const Fortran::parser::OmpObject &ompObject : objectList.v) {
Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject);
addOperands(*sym);
}
}

mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter,
std::size_t loopVarTypeSize) {
// OpenMP runtime requires 32-bit or 64-bit loop variables.
Expand Down
6 changes: 2 additions & 4 deletions flang/lib/Lower/OpenMP/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,15 @@ void gatherFuncAndVarSyms(
const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause,
llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause);

int64_t getCollapseValue(const List<Clause> &clauses);

Fortran::semantics::Symbol *
getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject);

void genObjectList(const ObjectList &objects,
Fortran::lower::AbstractConverter &converter,
llvm::SmallVectorImpl<mlir::Value> &operands);

void genObjectList2(const Fortran::parser::OmpObjectList &objectList,
Fortran::lower::AbstractConverter &converter,
llvm::SmallVectorImpl<mlir::Value> &operands);

} // namespace omp
} // namespace lower
} // namespace Fortran
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace fir {
#include "flang/Optimizer/Transforms/Passes.h.inc"
} // namespace fir

#define DEBUG_TYPE "flang-add-debug-foundation"
#define DEBUG_TYPE "flang-add-debug-info"

namespace {

Expand Down
4 changes: 4 additions & 0 deletions flang/lib/Semantics/check-cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,10 @@ void CUDAChecker::Enter(const parser::AssignmentStmt &x) {
}

const evaluate::Assignment *assign{semantics::GetAssignment(x)};
if (!assign) {
return;
}

int nbLhs{evaluate::GetNbOfCUDASymbols(assign->lhs)};
int nbRhs{evaluate::GetNbOfCUDASymbols(assign->rhs)};

Expand Down
8 changes: 8 additions & 0 deletions flang/test/Semantics/cuf11.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,11 @@ subroutine sub1()
ahost = adev + adev

end subroutine

logical function compare_h(a,b)
!ERROR: Derived type 'h' not found
type(h) :: a, b
!ERROR: 'a' is not an object of derived type; it is implicitly typed
!ERROR: 'b' is not an object of derived type; it is implicitly typed
compare_h = (a%h .eq. b%h)
end
55 changes: 41 additions & 14 deletions libclc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
set( LIBCLC_MIN_LLVM 3.9.0 )

set( LIBCLC_TARGETS_TO_BUILD "all"
CACHE STRING "Semicolon-separated list of targets to build, or 'all'." )
CACHE STRING "Semicolon-separated list of libclc targets to build, or 'all'." )

option( ENABLE_RUNTIME_SUBNORMAL "Enable runtime linking of subnormal support." OFF )

Expand All @@ -50,11 +50,13 @@ if( LIBCLC_STANDALONE_BUILD OR CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DI
endif()

# Import required tools as targets
foreach( tool IN ITEMS clang llvm-as llvm-link opt )
find_program( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
add_executable( libclc::${tool} IMPORTED GLOBAL )
set_target_properties( libclc::${tool} PROPERTIES IMPORTED_LOCATION ${LLVM_TOOL_${tool}} )
endforeach()
if( NOT EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} )
foreach( tool IN ITEMS clang llvm-as llvm-link opt )
find_program( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
add_executable( libclc::${tool} IMPORTED GLOBAL )
set_target_properties( libclc::${tool} PROPERTIES IMPORTED_LOCATION ${LLVM_TOOL_${tool}} )
endforeach()
endif()
else()
# In-tree configuration
set( LIBCLC_STANDALONE_BUILD FALSE )
Expand All @@ -68,19 +70,44 @@ else()
message(FATAL_ERROR "Clang is not enabled, but is required to build libclc in-tree")
endif()

if( NOT EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} )
foreach( tool IN ITEMS clang llvm-as llvm-link opt )
add_executable(libclc::${tool} ALIAS ${tool})
endforeach()
endif()
endif()

if( EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} )
message( WARNING "Using custom LLVM tools to build libclc: "
"${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR}, "
" ensure the tools are up to date." )
# Note - use a differently named variable than LLVM_TOOL_${tool} as above, as
# the variable name is used to cache the result of find_program. If we used
# the same name, a user wouldn't be able to switch a build between default
# and custom tools.
foreach( tool IN ITEMS clang llvm-as llvm-link opt )
add_executable(libclc::${tool} ALIAS ${tool})
find_program( LLVM_CUSTOM_TOOL_${tool} ${tool}
PATHS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
add_executable( libclc::${tool} IMPORTED GLOBAL )
set_target_properties( libclc::${tool} PROPERTIES
IMPORTED_LOCATION ${LLVM_CUSTOM_TOOL_${tool}} )
endforeach()
endif()

if( NOT TARGET libclc::clang OR NOT TARGET libclc::opt
OR NOT TARGET libclc::llvm-as OR NOT TARGET libclc::llvm-link )
message( FATAL_ERROR "libclc toolchain incomplete!" )
endif()
foreach( tool IN ITEMS clang opt llvm-as llvm-link )
if( NOT TARGET libclc::${tool} )
message( FATAL_ERROR "libclc toolchain incomplete - missing tool ${tool}!" )
endif()
endforeach()

# llvm-spirv is an optional dependency, used to build spirv-* targets.
find_program( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )

if( LLVM_SPIRV )
add_executable( libclc::llvm-spirv IMPORTED GLOBAL )
set_target_properties( libclc::llvm-spirv PROPERTIES IMPORTED_LOCATION ${LLVM_SPIRV} )
endif()

# List of all targets. Note that some are added dynamically below.
set( LIBCLC_TARGETS_ALL
amdgcn--
Expand All @@ -101,7 +128,7 @@ endif()

# spirv-mesa3d and spirv64-mesa3d targets can only be built with the (optional)
# llvm-spirv external tool.
if( LLVM_SPIRV )
if( TARGET libclc::llvm-spirv )
list( APPEND LIBCLC_TARGETS_ALL spirv-mesa3d- spirv64-mesa3d- )
endif()

Expand All @@ -114,7 +141,7 @@ list( SORT LIBCLC_TARGETS_TO_BUILD )
# Verify that the user hasn't requested mesa3d targets without an available
# llvm-spirv tool.
if( "spirv-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD OR "spirv64-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD )
if( NOT LLVM_SPIRV )
if( NOT TARGET libclc::llvm-spirv )
message( FATAL_ERROR "SPIR-V targets requested, but spirv-tools is not installed" )
endif()
endif()
Expand Down Expand Up @@ -363,7 +390,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
if( ARCH STREQUAL spirv OR ARCH STREQUAL spirv64 )
set( spv_suffix ${arch_suffix}.spv )
add_custom_command( OUTPUT ${spv_suffix}
COMMAND ${LLVM_SPIRV} ${spvflags} -o ${spv_suffix} ${builtins_link_lib}
COMMAND libclc::llvm-spirv ${spvflags} -o ${spv_suffix} ${builtins_link_lib}
DEPENDS ${builtins_link_lib}
)
add_custom_target( "prepare-${spv_suffix}" ALL DEPENDS "${spv_suffix}" )
Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/FormatPaper.csv
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Section,Description,Dependencies,Assignee,Status,First released version
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_weekday_last``",,Mark de Wever,|Complete|,16.0
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::hh_mm_ss<duration<Rep, Period>>``",,Mark de Wever,|Complete|,17.0
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::sys_info``",,Mark de Wever,|Complete|,19.0
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::local_info``",A ``<chrono>`` implementation,Mark de Wever,,
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::local_info``",,Mark de Wever,|Complete|,19.0
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::zoned_time<Duration, TimeZonePtr>``",A ``<chrono>`` implementation,Mark de Wever,,

"`P2693R1 <https://wg21.link/P2693R1>`__","Formatting ``thread::id`` and ``stacktrace``"
Expand Down
17 changes: 9 additions & 8 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,6 @@ set(files
__algorithm/pop_heap.h
__algorithm/prev_permutation.h
__algorithm/pstl_any_all_none_of.h
__algorithm/pstl_backends/cpu_backends/any_of.h
__algorithm/pstl_backends/cpu_backends/fill.h
__algorithm/pstl_backends/cpu_backends/find_if.h
__algorithm/pstl_backends/cpu_backends/for_each.h
__algorithm/pstl_backends/cpu_backends/merge.h
__algorithm/pstl_backends/cpu_backends/stable_sort.h
__algorithm/pstl_backends/cpu_backends/transform.h
__algorithm/pstl_backends/cpu_backends/transform_reduce.h
__algorithm/pstl_copy.h
__algorithm/pstl_count.h
__algorithm/pstl_equal.h
Expand Down Expand Up @@ -278,6 +270,7 @@ set(files
__chrono/high_resolution_clock.h
__chrono/leap_second.h
__chrono/literals.h
__chrono/local_info.h
__chrono/month.h
__chrono/month_weekday.h
__chrono/monthday.h
Expand Down Expand Up @@ -593,7 +586,15 @@ set(files
__pstl/backends/std_thread.h
__pstl/configuration.h
__pstl/configuration_fwd.h
__pstl/cpu_algos/any_of.h
__pstl/cpu_algos/cpu_traits.h
__pstl/cpu_algos/fill.h
__pstl/cpu_algos/find_if.h
__pstl/cpu_algos/for_each.h
__pstl/cpu_algos/merge.h
__pstl/cpu_algos/stable_sort.h
__pstl/cpu_algos/transform.h
__pstl/cpu_algos/transform_reduce.h
__random/bernoulli_distribution.h
__random/binomial_distribution.h
__random/cauchy_distribution.h
Expand Down
3 changes: 3 additions & 0 deletions libcxx/include/__chrono/convert_to_tm.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <__chrono/duration.h>
#include <__chrono/file_clock.h>
#include <__chrono/hh_mm_ss.h>
#include <__chrono/local_info.h>
#include <__chrono/month.h>
#include <__chrono/month_weekday.h>
#include <__chrono/monthday.h>
Expand Down Expand Up @@ -175,6 +176,8 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) {
# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
} else if constexpr (same_as<_ChronoT, chrono::sys_info>) {
// Has no time information.
} else if constexpr (same_as<_ChronoT, chrono::local_info>) {
// Has no time information.
# endif
} else
static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization");
Expand Down
20 changes: 20 additions & 0 deletions libcxx/include/__chrono/formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <__chrono/duration.h>
#include <__chrono/file_clock.h>
#include <__chrono/hh_mm_ss.h>
#include <__chrono/local_info.h>
#include <__chrono/month.h>
#include <__chrono/month_weekday.h>
#include <__chrono/monthday.h>
Expand Down Expand Up @@ -419,6 +420,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) {
# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
else if constexpr (same_as<_Tp, chrono::sys_info>)
return true;
else if constexpr (same_as<_Tp, chrono::local_info>)
return true;
# endif
else
static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
Expand Down Expand Up @@ -463,6 +466,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) {
# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
else if constexpr (same_as<_Tp, chrono::sys_info>)
return true;
else if constexpr (same_as<_Tp, chrono::local_info>)
return true;
# endif
else
static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
Expand Down Expand Up @@ -507,6 +512,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) {
# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
else if constexpr (same_as<_Tp, chrono::sys_info>)
return true;
else if constexpr (same_as<_Tp, chrono::local_info>)
return true;
# endif
else
static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
Expand Down Expand Up @@ -551,6 +558,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
# if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
else if constexpr (same_as<_Tp, chrono::sys_info>)
return true;
else if constexpr (same_as<_Tp, chrono::local_info>)
return true;
# endif
else
static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
Expand Down Expand Up @@ -893,6 +902,17 @@ struct formatter<chrono::sys_info, _CharT> : public __formatter_chrono<_CharT> {
return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time_zone);
}
};

template <__fmt_char_type _CharT>
struct formatter<chrono::local_info, _CharT> : public __formatter_chrono<_CharT> {
public:
using _Base = __formatter_chrono<_CharT>;

template <class _ParseContext>
_LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags{});
}
};
# endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)

#endif // if _LIBCPP_STD_VER >= 20
Expand Down
50 changes: 50 additions & 0 deletions libcxx/include/__chrono/local_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html

#ifndef _LIBCPP___CHRONO_LOCAL_INFO_H
#define _LIBCPP___CHRONO_LOCAL_INFO_H

#include <version>
// Enable the contents of the header only when libc++ was built with experimental features enabled.
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)

# include <__chrono/sys_info.h>
# include <__config>

# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif

_LIBCPP_BEGIN_NAMESPACE_STD

# if _LIBCPP_STD_VER >= 20

namespace chrono {

struct local_info {
static constexpr int unique = 0;
static constexpr int nonexistent = 1;
static constexpr int ambiguous = 2;

int result;
sys_info first;
sys_info second;
};

} // namespace chrono

# endif // _LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)

#endif // _LIBCPP___CHRONO_LOCAL_INFO_H
22 changes: 22 additions & 0 deletions libcxx/include/__chrono/ostream.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <__chrono/duration.h>
#include <__chrono/file_clock.h>
#include <__chrono/hh_mm_ss.h>
#include <__chrono/local_info.h>
#include <__chrono/month.h>
#include <__chrono/month_weekday.h>
#include <__chrono/monthday.h>
Expand Down Expand Up @@ -280,6 +281,27 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __info) {
__abbrev);
}

template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __info) {
auto __result = [&]() -> basic_string<_CharT> {
switch (__info.result) {
case local_info::unique:
return _LIBCPP_STATICALLY_WIDEN(_CharT, "unique");
case local_info::nonexistent:
return _LIBCPP_STATICALLY_WIDEN(_CharT, "non-existent");
case local_info::ambiguous:
return _LIBCPP_STATICALLY_WIDEN(_CharT, "ambiguous");

default:
return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "unspecified result ({})"), __info.result);
};
};

return __os << std::format(
_LIBCPP_STATICALLY_WIDEN(_CharT, "{}: {{{}, {}}}"), __result(), __info.first, __info.second);
}

# endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)

} // namespace chrono
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__format/format_arg.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <__fwd/format.h>
#include <__memory/addressof.h>
#include <__type_traits/conditional.h>
#include <__type_traits/remove_const.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
Expand Down
16 changes: 8 additions & 8 deletions libcxx/include/__pstl/backends/libdispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,13 +349,13 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS

// Implement PSTL algorithms based on the __cpu_traits specialized above
#include <__algorithm/pstl_backends/cpu_backends/any_of.h>
#include <__algorithm/pstl_backends/cpu_backends/fill.h>
#include <__algorithm/pstl_backends/cpu_backends/find_if.h>
#include <__algorithm/pstl_backends/cpu_backends/for_each.h>
#include <__algorithm/pstl_backends/cpu_backends/merge.h>
#include <__algorithm/pstl_backends/cpu_backends/stable_sort.h>
#include <__algorithm/pstl_backends/cpu_backends/transform.h>
#include <__algorithm/pstl_backends/cpu_backends/transform_reduce.h>
#include <__pstl/cpu_algos/any_of.h>
#include <__pstl/cpu_algos/fill.h>
#include <__pstl/cpu_algos/find_if.h>
#include <__pstl/cpu_algos/for_each.h>
#include <__pstl/cpu_algos/merge.h>
#include <__pstl/cpu_algos/stable_sort.h>
#include <__pstl/cpu_algos/transform.h>
#include <__pstl/cpu_algos/transform_reduce.h>

#endif // _LIBCPP___PSTL_BACKENDS_LIBDISPATCH_H
16 changes: 8 additions & 8 deletions libcxx/include/__pstl/backends/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ _LIBCPP_POP_MACROS
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17

// Implement PSTL algorithms based on the __cpu_traits specialized above
#include <__algorithm/pstl_backends/cpu_backends/any_of.h>
#include <__algorithm/pstl_backends/cpu_backends/fill.h>
#include <__algorithm/pstl_backends/cpu_backends/find_if.h>
#include <__algorithm/pstl_backends/cpu_backends/for_each.h>
#include <__algorithm/pstl_backends/cpu_backends/merge.h>
#include <__algorithm/pstl_backends/cpu_backends/stable_sort.h>
#include <__algorithm/pstl_backends/cpu_backends/transform.h>
#include <__algorithm/pstl_backends/cpu_backends/transform_reduce.h>
#include <__pstl/cpu_algos/any_of.h>
#include <__pstl/cpu_algos/fill.h>
#include <__pstl/cpu_algos/find_if.h>
#include <__pstl/cpu_algos/for_each.h>
#include <__pstl/cpu_algos/merge.h>
#include <__pstl/cpu_algos/stable_sort.h>
#include <__pstl/cpu_algos/transform.h>
#include <__pstl/cpu_algos/transform_reduce.h>

#endif // _LIBCPP___PSTL_BACKENDS_SERIAL_H
16 changes: 8 additions & 8 deletions libcxx/include/__pstl/backends/std_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS

// Implement PSTL algorithms based on the __cpu_traits specialized above
#include <__algorithm/pstl_backends/cpu_backends/any_of.h>
#include <__algorithm/pstl_backends/cpu_backends/fill.h>
#include <__algorithm/pstl_backends/cpu_backends/find_if.h>
#include <__algorithm/pstl_backends/cpu_backends/for_each.h>
#include <__algorithm/pstl_backends/cpu_backends/merge.h>
#include <__algorithm/pstl_backends/cpu_backends/stable_sort.h>
#include <__algorithm/pstl_backends/cpu_backends/transform.h>
#include <__algorithm/pstl_backends/cpu_backends/transform_reduce.h>
#include <__pstl/cpu_algos/any_of.h>
#include <__pstl/cpu_algos/fill.h>
#include <__pstl/cpu_algos/find_if.h>
#include <__pstl/cpu_algos/for_each.h>
#include <__pstl/cpu_algos/merge.h>
#include <__pstl/cpu_algos/stable_sort.h>
#include <__pstl/cpu_algos/transform.h>
#include <__pstl/cpu_algos/transform_reduce.h>

#endif // _LIBCPP___PSTL_BACKENDS_STD_THREAD_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
#ifndef _LIBCPP___PSTL_CPU_ALGOS_ANY_OF_H
#define _LIBCPP___PSTL_CPU_ALGOS_ANY_OF_H

#include <__algorithm/any_of.h>
#include <__algorithm/find_if.h>
Expand Down Expand Up @@ -96,4 +96,4 @@ _LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17

#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
#endif // _LIBCPP___PSTL_CPU_ALGOS_ANY_OF_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
#ifndef _LIBCPP___PSTL_CPU_ALGOS_FILL_H
#define _LIBCPP___PSTL_CPU_ALGOS_FILL_H

#include <__algorithm/fill.h>
#include <__config>
Expand Down Expand Up @@ -60,4 +60,4 @@ _LIBCPP_END_NAMESPACE_STD

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17

#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
#endif // _LIBCPP___PSTL_CPU_ALGOS_FILL_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
#ifndef _LIBCPP___PSTL_CPU_ALGOS_FIND_IF_H
#define _LIBCPP___PSTL_CPU_ALGOS_FIND_IF_H

#include <__algorithm/find_if.h>
#include <__atomic/atomic.h>
Expand Down Expand Up @@ -132,4 +132,4 @@ _LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17

#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
#endif // _LIBCPP___PSTL_CPU_ALGOS_FIND_IF_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
#ifndef _LIBCPP___PSTL_CPU_ALGOS_FOR_EACH_H
#define _LIBCPP___PSTL_CPU_ALGOS_FOR_EACH_H

#include <__algorithm/for_each.h>
#include <__config>
Expand Down Expand Up @@ -60,4 +60,4 @@ _LIBCPP_END_NAMESPACE_STD

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17

#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
#endif // _LIBCPP___PSTL_CPU_ALGOS_FOR_EACH_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
#ifndef _LIBCPP___PSTL_CPU_ALGOS_MERGE_H
#define _LIBCPP___PSTL_CPU_ALGOS_MERGE_H

#include <__algorithm/merge.h>
#include <__config>
Expand Down Expand Up @@ -83,4 +83,4 @@ _LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17

#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
#endif // _LIBCPP___PSTL_CPU_ALGOS_MERGE_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
#ifndef _LIBCPP___PSTL_CPU_ALGOS_STABLE_SORT_H
#define _LIBCPP___PSTL_CPU_ALGOS_STABLE_SORT_H

#include <__algorithm/stable_sort.h>
#include <__config>
Expand Down Expand Up @@ -43,4 +43,4 @@ _LIBCPP_END_NAMESPACE_STD

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17

#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
#endif // _LIBCPP___PSTL_CPU_ALGOS_STABLE_SORT_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
#ifndef _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_H
#define _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_H

#include <__algorithm/transform.h>
#include <__config>
Expand Down Expand Up @@ -136,4 +136,4 @@ _LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17

#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
#endif // _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
#ifndef _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H
#define _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H

#include <__config>
#include <__iterator/concepts.h>
Expand Down Expand Up @@ -203,4 +203,4 @@ _LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
#endif // _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H
2 changes: 0 additions & 2 deletions libcxx/include/__type_traits/remove_cv.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
#define _LIBCPP___TYPE_TRAITS_REMOVE_CV_H

#include <__config>
#include <__type_traits/remove_const.h>
#include <__type_traits/remove_volatile.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand Down
16 changes: 16 additions & 0 deletions libcxx/include/chrono
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,20 @@ template<class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const sys_info& si);

struct local_info { // C++20
static constexpr int unique = 0;
static constexpr int nonexistent = 1;
static constexpr int ambiguous = 2;

int result;
sys_info first;
sys_info second;
};

template<class charT, class traits> // C++20
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const local_info& li);

// 25.10.5, class time_zone // C++20
enum class choose {earliest, latest};
class time_zone {
Expand Down Expand Up @@ -834,6 +848,7 @@ namespace std {
template<class Rep, class Period, class charT>
struct formatter<chrono::hh_mm_ss<duration<Rep, Period>>, charT>; // C++20
template<class charT> struct formatter<chrono::sys_info, charT>; // C++20
template<class charT> struct formatter<chrono::local_info, charT>; // C++20
} // namespace std

namespace chrono {
Expand Down Expand Up @@ -899,6 +914,7 @@ constexpr chrono::year operator ""y(unsigned lo
# include <__chrono/day.h>
# include <__chrono/hh_mm_ss.h>
# include <__chrono/literals.h>
# include <__chrono/local_info.h>
# include <__chrono/month.h>
# include <__chrono/month_weekday.h>
# include <__chrono/monthday.h>
Expand Down
9 changes: 1 addition & 8 deletions libcxx/include/libcxx.imp
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,6 @@
{ include: [ "<__algorithm/pop_heap.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/prev_permutation.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_any_all_none_of.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_backends/cpu_backends/any_of.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_backends/cpu_backends/fill.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_backends/cpu_backends/find_if.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_backends/cpu_backends/for_each.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_backends/cpu_backends/merge.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_backends/cpu_backends/stable_sort.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_backends/cpu_backends/transform.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_backends/cpu_backends/transform_reduce.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_copy.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_count.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_equal.h>", "private", "<algorithm>", "public" ] },
Expand Down Expand Up @@ -275,6 +267,7 @@
{ include: [ "<__chrono/high_resolution_clock.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/leap_second.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/literals.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/local_info.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/month.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/month_weekday.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/monthday.h>", "private", "<chrono>", "public" ] },
Expand Down
29 changes: 15 additions & 14 deletions libcxx/include/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -714,14 +714,6 @@ module std_private_algorithm_partition_point [system
module std_private_algorithm_pop_heap [system] { header "__algorithm/pop_heap.h" }
module std_private_algorithm_prev_permutation [system] { header "__algorithm/prev_permutation.h" }
module std_private_algorithm_pstl_any_all_none_of [system] { header "__algorithm/pstl_any_all_none_of.h" }
module std_private_algorithm_pstl_backends_cpu_backends_any_of [system] { textual header "__algorithm/pstl_backends/cpu_backends/any_of.h" }
module std_private_algorithm_pstl_backends_cpu_backends_fill [system] { textual header "__algorithm/pstl_backends/cpu_backends/fill.h" }
module std_private_algorithm_pstl_backends_cpu_backends_find_if [system] { textual header "__algorithm/pstl_backends/cpu_backends/find_if.h" }
module std_private_algorithm_pstl_backends_cpu_backends_for_each [system] { textual header "__algorithm/pstl_backends/cpu_backends/for_each.h" }
module std_private_algorithm_pstl_backends_cpu_backends_merge [system] { textual header "__algorithm/pstl_backends/cpu_backends/merge.h" }
module std_private_algorithm_pstl_backends_cpu_backends_stable_sort [system] { textual header "__algorithm/pstl_backends/cpu_backends/stable_sort.h" }
module std_private_algorithm_pstl_backends_cpu_backends_transform [system] { textual header "__algorithm/pstl_backends/cpu_backends/transform.h" }
module std_private_algorithm_pstl_backends_cpu_backends_transform_reduce [system] { textual header "__algorithm/pstl_backends/cpu_backends/transform_reduce.h" }
module std_private_algorithm_pstl_copy [system] { header "__algorithm/pstl_copy.h" }
module std_private_algorithm_pstl_count [system] { header "__algorithm/pstl_count.h" }
module std_private_algorithm_pstl_equal [system] { header "__algorithm/pstl_equal.h" }
Expand Down Expand Up @@ -1132,6 +1124,7 @@ module std_private_chrono_high_resolution_clock [system] {
}
module std_private_chrono_leap_second [system] { header "__chrono/leap_second.h" }
module std_private_chrono_literals [system] { header "__chrono/literals.h" }
module std_private_chrono_local_info [system] { header "__chrono/local_info.h" }
module std_private_chrono_month [system] { header "__chrono/month.h" }
module std_private_chrono_month_weekday [system] { header "__chrono/month_weekday.h" }
module std_private_chrono_monthday [system] { header "__chrono/monthday.h" }
Expand Down Expand Up @@ -1595,15 +1588,23 @@ module std_private_numeric_transform_exclusive_scan [system] { header "__numeric
module std_private_numeric_transform_inclusive_scan [system] { header "__numeric/transform_inclusive_scan.h" }
module std_private_numeric_transform_reduce [system] { header "__numeric/transform_reduce.h" }

module std_private_pstl_backends_libdispatch [system] { header "__pstl/backends/libdispatch.h" }
module std_private_pstl_backends_serial [system] { header "__pstl/backends/serial.h" }
module std_private_pstl_backends_std_thread [system] { header "__pstl/backends/std_thread.h" }
module std_private_pstl_cpu_algos_cpu_traits [system] { header "__pstl/cpu_algos/cpu_traits.h" }
module std_private_pstl_configuration_fwd [system] {
module std_private_pstl_backends_libdispatch [system] { header "__pstl/backends/libdispatch.h" }
module std_private_pstl_backends_serial [system] { header "__pstl/backends/serial.h" }
module std_private_pstl_backends_std_thread [system] { header "__pstl/backends/std_thread.h" }
module std_private_pstl_cpu_algos_any_of [system] { textual header "__pstl/cpu_algos/any_of.h" }
module std_private_pstl_cpu_algos_cpu_traits [system] { header "__pstl/cpu_algos/cpu_traits.h" }
module std_private_pstl_cpu_algos_fill [system] { textual header "__pstl/cpu_algos/fill.h" }
module std_private_pstl_cpu_algos_find_if [system] { textual header "__pstl/cpu_algos/find_if.h" }
module std_private_pstl_cpu_algos_for_each [system] { textual header "__pstl/cpu_algos/for_each.h" }
module std_private_pstl_cpu_algos_merge [system] { textual header "__pstl/cpu_algos/merge.h" }
module std_private_pstl_cpu_algos_stable_sort [system] { textual header "__pstl/cpu_algos/stable_sort.h" }
module std_private_pstl_cpu_algos_transform [system] { textual header "__pstl/cpu_algos/transform.h" }
module std_private_pstl_cpu_algos_transform_reduce [system] { textual header "__pstl/cpu_algos/transform_reduce.h" }
module std_private_pstl_configuration_fwd [system] {
header "__pstl/configuration_fwd.h"
export *
}
module std_private_pstl_configuration [system] {
module std_private_pstl_configuration [system] {
header "__pstl/configuration.h"
export *
}
Expand Down
1 change: 1 addition & 0 deletions libcxx/modules/std/chrono.inc
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export namespace std {
# endif // if 0

// [time.zone.info], information classes
using std::chrono::local_info;
using std::chrono::sys_info;

# if 0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization

// TODO FMT This test should not require std::to_chars(floating-point)
// XFAIL: availability-fp_to_chars-missing

// XFAIL: libcpp-has-no-incomplete-tzdb

// <chrono>

// template<class charT, class traits>
// basic_ostream<charT, traits>&
// operator<<(basic_ostream<charT, traits>& os, const local_info& r);

// [time.zone.info.local]
// 7 Effects: Streams out the local_info object r in an unspecified format.
// 8 Returns: os.
//
// Tests the output produced by this function.

#include <cassert>
#include <chrono>
#include <memory>
#include <sstream>

#include "assert_macros.h"
#include "test_macros.h"
#include "make_string.h"
#include "concat_macros.h"

#define SV(S) MAKE_STRING_VIEW(CharT, S)

template <class CharT>
static void test(std::basic_string_view<CharT> expected, std::chrono::local_info&& info) {
std::basic_stringstream<CharT> sstr;
sstr << info;
std::basic_string<CharT> output = sstr.str();

TEST_REQUIRE(expected == output,
TEST_WRITE_CONCATENATED("\nExpected output ", expected, "\nActual output ", output, '\n'));
}

template <class CharT>
static void test() {
using namespace std::literals::chrono_literals;
namespace tz = std::chrono;
// result values matching the "known" results
test(SV("unique: "
"{[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min \"TZ\", "
"[1970-01-01 00:00:00, 1970-01-01 00:00:00) 00:00:00 0min \"\"}"),
tz::local_info{tz::local_info::unique,
tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"},
tz::sys_info{}});

test(SV("non-existent: "
"{[1970-01-01 00:00:00, 2038-12-31 00:00:00) 12:23:45 -67min \"NEG\", "
"[1970-01-01 00:00:00, 2038-12-31 00:00:00) -12:23:45 67min \"POS\"}"),
tz::local_info{
tz::local_info::nonexistent,
tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
12h + 23min + 45s,
-67min,
"NEG"},
tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
-(12h + 23min + 45s),
67min,
"POS"}});

test(SV("ambiguous: "
"{[1970-01-01 00:00:00, 2038-12-31 00:00:00) 12:23:45 -67min \"NEG\", "
"[1970-01-01 00:00:00, 2038-12-31 00:00:00) -12:23:45 67min \"POS\"}"),
tz::local_info{
tz::local_info::ambiguous,
tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
12h + 23min + 45s,
-67min,
"NEG"},
tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
-(12h + 23min + 45s),
67min,
"POS"}});

// result values not matching the "known" results
test(
SV("unspecified result (-1): "
"{[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min \"TZ\", "
"[1970-01-01 00:00:00, 1970-01-01 00:00:00) 00:00:00 0min \"\"}"),
tz::local_info{-1, tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"}, tz::sys_info{}});
test(SV("unspecified result (3): "
"{[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min \"TZ\", "
"[1970-01-01 00:00:00, 1970-01-01 00:00:00) 00:00:00 0min \"\"}"),
tz::local_info{3, tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"}, tz::sys_info{}});
}

int main(int, const char**) {
test<char>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <tuple>

#include "test_iterators.h"
#include "test_range.h"

constexpr void compareOperatorTest(const auto& iter1, const auto& iter2) {
assert(!(iter1 < iter1));
Expand Down Expand Up @@ -139,8 +140,7 @@ constexpr bool test() {
auto it = ev.begin();

using ElemIter = decltype(it);
static_assert(!std::invocable<std::equal_to<>, ElemIter, ElemIter>);
static_assert(!std::invocable<std::not_equal_to<>, ElemIter, ElemIter>);
static_assert(!weakly_equality_comparable_with<ElemIter, ElemIter>);
inequalityOperatorsDoNotExistTest(it, it);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <ranges>

#include "../types.h"
#include "test_range.h"

template <bool Const>
struct Iter {
Expand Down Expand Up @@ -63,37 +64,33 @@ struct Range : TupleBufferView {
using R = Range<Sent>;
using CrossComparableR = Range<CrossComparableSent>;

// Test Constraint
template <class I, class S>
concept HasEqual = requires(const I i, const S s) { i == s; };

using std::ranges::elements_view;
using std::ranges::iterator_t;
using std::ranges::sentinel_t;

static_assert(HasEqual<iterator_t<elements_view<R, 0>>, //
sentinel_t<elements_view<R, 0>>>);
static_assert(weakly_equality_comparable_with<iterator_t<elements_view<R, 0>>, //
sentinel_t<elements_view<R, 0>>>);

static_assert(!HasEqual<iterator_t<const elements_view<R, 0>>, //
sentinel_t<elements_view<R, 0>>>);
static_assert(!weakly_equality_comparable_with<iterator_t<const elements_view<R, 0>>, //
sentinel_t<elements_view<R, 0>>>);

static_assert(!HasEqual<iterator_t<elements_view<R, 0>>, //
sentinel_t<const elements_view<R, 0>>>);
static_assert(!weakly_equality_comparable_with<iterator_t<elements_view<R, 0>>, //
sentinel_t<const elements_view<R, 0>>>);

static_assert(HasEqual<iterator_t<const elements_view<R, 0>>, //
sentinel_t<const elements_view<R, 0>>>);
static_assert(weakly_equality_comparable_with<iterator_t<const elements_view<R, 0>>, //
sentinel_t<const elements_view<R, 0>>>);

static_assert(HasEqual<iterator_t<elements_view<R, 0>>, //
sentinel_t<elements_view<R, 0>>>);
static_assert(weakly_equality_comparable_with<iterator_t<elements_view<CrossComparableR, 0>>, //
sentinel_t<elements_view<CrossComparableR, 0>>>);

static_assert(HasEqual<iterator_t<const elements_view<CrossComparableR, 0>>, //
sentinel_t<elements_view<CrossComparableR, 0>>>);
static_assert(weakly_equality_comparable_with<iterator_t<const elements_view<CrossComparableR, 0>>, //
sentinel_t<elements_view<CrossComparableR, 0>>>);

static_assert(HasEqual<iterator_t<elements_view<CrossComparableR, 0>>, //
sentinel_t<const elements_view<CrossComparableR, 0>>>);
static_assert(weakly_equality_comparable_with<iterator_t<elements_view<CrossComparableR, 0>>, //
sentinel_t<const elements_view<CrossComparableR, 0>>>);

static_assert(HasEqual<iterator_t<const elements_view<CrossComparableR, 0>>, //
sentinel_t<const elements_view<CrossComparableR, 0>>>);
static_assert(weakly_equality_comparable_with<iterator_t<const elements_view<CrossComparableR, 0>>, //
sentinel_t<const elements_view<CrossComparableR, 0>>>);

template <class R, bool ConstIter, bool ConstSent>
constexpr void testOne() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
#include <cassert>
#include <concepts>
#include <utility>

#include "test_iterators.h"
#include "test_macros.h"
#include "../types.h"
#include "test_range.h"

template <class T>
concept has_equal = requires (T const& x, T const& y) { { x == y }; };
#include "../types.h"

template <class Iterator>
constexpr void test() {
Expand Down Expand Up @@ -76,7 +76,7 @@ constexpr bool tests() {
using Sentinel = sentinel_wrapper<Iterator>;
using FilterView = std::ranges::filter_view<minimal_view<Iterator, Sentinel>, AlwaysTrue>;
using FilterIterator = std::ranges::iterator_t<FilterView>;
static_assert(!has_equal<FilterIterator>);
static_assert(!weakly_equality_comparable_with<FilterIterator, FilterIterator>);
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
#include <type_traits>

#include "../types.h"

template <class Iter, class Sent>
concept EqualityComparable = std::invocable<std::equal_to<>, const Iter&, const Sent&> ;
#include "test_range.h"

using Iterator = random_access_iterator<BufferView<int*>*>;
using ConstIterator = random_access_iterator<const BufferView<int*>*>;
Expand Down Expand Up @@ -53,10 +51,10 @@ struct ConstComparableView : BufferView<BufferView<int*>*> {
constexpr auto end() const { return ConstComparableSentinel<true>(ConstIterator(data_ + size_)); }
};

static_assert(EqualityComparable<std::ranges::iterator_t<ConstComparableView>,
std::ranges::sentinel_t<const ConstComparableView>>);
static_assert(EqualityComparable<std::ranges::iterator_t<const ConstComparableView>,
std::ranges::sentinel_t<ConstComparableView>>);
static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<ConstComparableView>,
std::ranges::sentinel_t<const ConstComparableView>>);
static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<const ConstComparableView>,
std::ranges::sentinel_t<ConstComparableView>>);

constexpr bool test() {
int buffer[4][4] = {{1111, 2222, 3333, 4444}, {555, 666, 777, 888}, {99, 1010, 1111, 1212}, {13, 14, 15, 16}};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@

#include <concepts>
#include <string_view>

#include "../types.h"

template <class Iter>
concept CanCallEquals = requires(const Iter& i) {
i == i;
i != i;
};
#include "test_range.h"

constexpr bool test() {
// When `View` is a forward range, `inner-iterator` supports both overloads of `operator==`.
Expand Down Expand Up @@ -56,7 +53,7 @@ constexpr bool test() {
auto b = val.begin();
std::same_as<std::default_sentinel_t> decltype(auto) e = val.end();

static_assert(!CanCallEquals<decltype(b)>);
static_assert(!weakly_equality_comparable_with<decltype(b), decltype(b)>);

assert(!(b == std::default_sentinel));
assert(b != std::default_sentinel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@

#include <concepts>
#include <string_view>

#include "../types.h"

template <class Iter>
concept CanCallEquals = requires(const Iter& i) {
i == i;
i != i;
};
#include "test_range.h"

constexpr bool test() {
// Forward range supports both overloads of `operator==`.
Expand Down Expand Up @@ -69,7 +66,7 @@ constexpr bool test() {
auto b = v.begin();
std::same_as<std::default_sentinel_t> decltype(auto) e = v.end();

static_assert(!CanCallEquals<decltype(b)>);
static_assert(!weakly_equality_comparable_with<decltype(b), decltype(b)>);

assert(!(b == std::default_sentinel));
assert(b != std::default_sentinel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,37 +70,33 @@ struct LessThan3 {
constexpr bool operator()(int i) const { return i < 3; }
};

// Test Constraint
template <class I, class S>
concept HasEqual = requires(const I i, const S s) { i == s; };

using std::ranges::iterator_t;
using std::ranges::sentinel_t;
using std::ranges::take_while_view;

static_assert(HasEqual<iterator_t<take_while_view<R, LessThan3>>, //
sentinel_t<take_while_view<R, LessThan3>>>);
static_assert(weakly_equality_comparable_with<iterator_t<take_while_view<R, LessThan3>>, //
sentinel_t<take_while_view<R, LessThan3>>>);

static_assert(!HasEqual<iterator_t<const take_while_view<R, LessThan3>>, //
sentinel_t<take_while_view<R, LessThan3>>>);
static_assert(!weakly_equality_comparable_with<iterator_t<const take_while_view<R, LessThan3>>, //
sentinel_t<take_while_view<R, LessThan3>>>);

static_assert(!HasEqual<iterator_t<take_while_view<R, LessThan3>>, //
sentinel_t<const take_while_view<R, LessThan3>>>);
static_assert(!weakly_equality_comparable_with<iterator_t<take_while_view<R, LessThan3>>, //
sentinel_t<const take_while_view<R, LessThan3>>>);

static_assert(HasEqual<iterator_t<const take_while_view<R, LessThan3>>, //
sentinel_t<const take_while_view<R, LessThan3>>>);
static_assert(weakly_equality_comparable_with<iterator_t<const take_while_view<R, LessThan3>>, //
sentinel_t<const take_while_view<R, LessThan3>>>);

static_assert(HasEqual<iterator_t<take_while_view<R, LessThan3>>, //
sentinel_t<take_while_view<R, LessThan3>>>);
static_assert(weakly_equality_comparable_with<iterator_t<take_while_view<CrossComparableR, LessThan3>>, //
sentinel_t<take_while_view<CrossComparableR, LessThan3>>>);

static_assert(HasEqual<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //
sentinel_t<take_while_view<CrossComparableR, LessThan3>>>);
static_assert(weakly_equality_comparable_with<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //
sentinel_t<take_while_view<CrossComparableR, LessThan3>>>);

static_assert(HasEqual<iterator_t<take_while_view<CrossComparableR, LessThan3>>, //
sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);
static_assert(weakly_equality_comparable_with<iterator_t<take_while_view<CrossComparableR, LessThan3>>, //
sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);

static_assert(HasEqual<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //
sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);
static_assert(weakly_equality_comparable_with<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //
sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);

template <class R, bool ConstIter, bool ConstSent>
constexpr void testOne() {
Expand Down
100 changes: 75 additions & 25 deletions libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
// constexpr auto begin() requires (!simple-view<V>);
// constexpr auto begin() const requires range<const V>;

#include <ranges>
#include <cassert>
#include <ranges>
#include <utility>

#include "test_macros.h"
#include "test_iterators.h"
Expand All @@ -27,55 +28,104 @@ struct NonCommonSimpleView : std::ranges::view_base {
static_assert(std::ranges::sized_range<NonCommonSimpleView>);
static_assert(!std::ranges::sized_range<const NonCommonSimpleView>);

using CommonInputIterPtrConstInt = common_input_iterator<const int*>;
using CountedCommonInputIterPtrConstInt = std::counted_iterator<CommonInputIterPtrConstInt>;

constexpr bool test() {
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};

// sized_range && random_access_iterator
// simple-view<V> && sized_range<V> && random_access_range<V>
{
std::ranges::take_view<SizedRandomAccessView> tv(SizedRandomAccessView(buffer), 4);
assert(tv.begin() == SizedRandomAccessView(buffer).begin());
ASSERT_SAME_TYPE(decltype(tv.begin()), RandomAccessIter);
}
using ViewTested = SizedRandomAccessView;
static_assert(simple_view<ViewTested>);
static_assert(std::ranges::sized_range<ViewTested>);
static_assert(std::ranges::random_access_range<ViewTested>);

{
const std::ranges::take_view<SizedRandomAccessView> tv(SizedRandomAccessView(buffer), 4);
assert(tv.begin() == SizedRandomAccessView(buffer).begin());
std::ranges::take_view<ViewTested> tv(ViewTested(buffer), 4);
assert(tv.begin() == ViewTested(buffer).begin());
ASSERT_SAME_TYPE(decltype(tv.begin()), RandomAccessIter);
}

// sized_range && !random_access_iterator
{
std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 4);
assert(tv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 4));
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<ForwardIter>);
const std::ranges::take_view<ViewTested> ctv(ViewTested(buffer), 4);
assert(ctv.begin() == ViewTested(buffer).begin());
ASSERT_SAME_TYPE(decltype(ctv.begin()), RandomAccessIter);
}

// simple-view<V> && sized_range<V> && !random_access_range<V>
{
const std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 4);
assert(tv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 4));
using ViewTested = SizedForwardView;
static_assert(simple_view<ViewTested>);
static_assert(std::ranges::sized_range<ViewTested>);
static_assert(!std::ranges::random_access_range<ViewTested>);

std::ranges::take_view<ViewTested> tv(ViewTested{buffer}, 16); // underlying size is 8
assert(tv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 8)); // expect min(8, 16)
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<ForwardIter>);

const std::ranges::take_view<ViewTested> ctv(ViewTested{buffer}, 4);
assert(ctv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 4));
ASSERT_SAME_TYPE(decltype(ctv.begin()), std::counted_iterator<ForwardIter>);
}

// !sized_range
// simple-view<V> && !sized_range<V>
{
std::ranges::take_view<MoveOnlyView> tv(MoveOnlyView{buffer}, 4);
using ViewTested = MoveOnlyView;
static_assert(simple_view<ViewTested>);
std::ranges::take_view<ViewTested> tv(ViewTested{buffer}, 4);
assert(tv.begin() == std::counted_iterator<int*>(buffer, 4));
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);

const std::ranges::take_view<ViewTested> ctv(ViewTested{buffer}, 4);
assert(ctv.begin() == std::counted_iterator<int*>(buffer, 4));
ASSERT_SAME_TYPE(decltype(ctv.begin()), std::counted_iterator<int*>);
}

// simple-view<V> && sized_range<V> && !sized_range<const V>
{
const std::ranges::take_view<MoveOnlyView> tv(MoveOnlyView{buffer}, 4);
assert(tv.begin() == std::counted_iterator<int*>(buffer, 4));
using ViewTested = NonCommonSimpleView;
static_assert(simple_view<ViewTested>);
static_assert(std::ranges::sized_range<ViewTested>);
static_assert(!std::ranges::sized_range<const ViewTested>);

std::ranges::take_view<ViewTested> tv{};
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);
ASSERT_SAME_TYPE(decltype(std::as_const(tv).begin()), std::counted_iterator<int*>);
}

// simple-view<V> && sized_range<V> && !size_range<!V>
// !simple-view<V> && !sized_range<V>
{
std::ranges::take_view<NonCommonSimpleView> tv{};
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);
ASSERT_SAME_TYPE(decltype(std::as_const(tv).begin()), std::counted_iterator<int*>);
using ViewTested = NonSimpleNonSizedView;
static_assert(!simple_view<ViewTested>);
static_assert(!std::ranges::sized_range<ViewTested>);

std::ranges::take_view<ViewTested> tv{ViewTested{buffer, buffer + 2}, 4};
// The count for the counted iterator is the count of the take_view (i.e., 4)
assert(tv.begin() == CountedCommonInputIterPtrConstInt(CommonInputIterPtrConstInt(buffer), 4));
ASSERT_SAME_TYPE(decltype(tv.begin()), CountedCommonInputIterPtrConstInt);
}

// !simple-view<V> && sized_range<V>
{
using ViewTested = NonSimpleSizedView;
static_assert(!simple_view<ViewTested>);
static_assert(std::ranges::sized_range<ViewTested>);

std::ranges::take_view<ViewTested> tv{ViewTested{buffer, buffer + 2}, 4};
// The count for the counted iterator is the min(2, 4) (i.e., 2).
assert(tv.begin() == CountedCommonInputIterPtrConstInt(CommonInputIterPtrConstInt(buffer), 2));
ASSERT_SAME_TYPE(decltype(tv.begin()), CountedCommonInputIterPtrConstInt);
}

// !simple-view<V> && sized_range<V> && random_access_range<V>
{
using ViewTested = NonSimpleSizedRandomView;
static_assert(!simple_view<ViewTested>);
static_assert(std::ranges::sized_range<ViewTested>);
static_assert(std::ranges::random_access_range<ViewTested>);

std::ranges::take_view<ViewTested> tv{ViewTested{buffer, buffer + 2}, 4};
assert(tv.begin() == random_access_iterator<const int*>(buffer));
ASSERT_SAME_TYPE(decltype(tv.begin()), random_access_iterator<const int*>);
}
return true;
}

Expand Down
14 changes: 14 additions & 0 deletions libcxx/test/std/ranges/range.adaptors/range.take/end.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ constexpr bool test() {
assert(tv.end() == std::ranges::next(tv.begin(), 8));
}

{
// __iterator<false> has base with type std::ranges::sentinel_t<NonSimpleViewNonSized>; adding a const qualifier
// would change the equality.
std::ranges::take_view<NonSimpleNonSizedView> tvns(NonSimpleNonSizedView{buffer, buffer + 8}, 0);
static_assert(!std::is_same_v<decltype(tvns.end().base()), std::ranges::sentinel_t<const NonSimpleNonSizedView>>);
}

{
// __iterator<true> has base with type std::ranges::sentinel_t<const NonSimpleViewNonSized>; adding a const qualifier
// would not change the equality.
std::ranges::take_view<SimpleViewNonSized> tvs(SimpleViewNonSized{buffer, buffer + 8}, 0);
static_assert(std::is_same_v<decltype(tvs.end().base()), std::ranges::sentinel_t<const SimpleViewNonSized>>);
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "test_comparisons.h"
#include "test_iterators.h"
#include "test_range.h"

template <bool Const>
using MaybeConstIterator = cpp20_input_iterator<std::conditional_t<Const, const int*, int*>>;
Expand Down Expand Up @@ -77,14 +78,6 @@ struct NonCrossConstComparableView : std::ranges::view_base {
static_assert(std::ranges::range<NonCrossConstComparableView>);
static_assert(std::ranges::range<const NonCrossConstComparableView>);

template <class T, class U>
concept weakly_equality_comparable_with = requires(const T& t, const U& u) {
t == u;
t != u;
u == t;
u != t;
};

constexpr bool test() {
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
using CrossConstComparableTakeView = std::ranges::take_view<CrossConstComparableView>;
Expand Down
Loading